The program:
$ cat foo.f
CHARACTER*15 FM
OPEN(1,FILE='foo.bin',FORM='UNFORMATTED')
WRITE(1) 1.0,2.0,3.0
CLOSE(1)
OPEN(2,FILE='foo.dat',FORM='FORMATTED')
WRITE(2,*) 1.0,2.0,3.0
CLOSE(2)
INQUIRE(FILE='foo.bin',FORM=FM)
PRINT *,'foo.bin: ',FM
INQUIRE(FILE='foo.dat',FORM=FM)
PRINT *,'foo.dat: ',FM
END
gives on Linux:
$ ./foo
foo.bin: FORMATTED
foo.dat: FORMATTED
while on HP-UX:
$ ./foo
foo.bin: UNFORMATTED
foo.dat: FORMATTED
Is there another way (portable) to check if file is
formatted or unformatted?
Regards.
Zlatko
> Is there another way (portable) to check if file is
> formatted or unformatted?
No. Because it is not uniquely defined whether a file is
formatted or unformatted. It is allowed for a file to
be readable both as formatted and unformatted.
One can check all kinds of things if one is willing to make
assumptions about the operating system and the file contents,
but there is no completely portable method.
The FORM= on INQUIRE doesn't do anything even close. It
tells you whether a file is *CURRENTLY CONNECTED* as formatted
or unformatted. If the file is not connected, it is supposed
to return "UNDEFINED". (So it looks like both the implementations
you tested are broken).
Closer to what you are asking for are the FORMATTED= and
UNFORMATTED= specifier in INQUIRE. THey tell you whether the
file can be connected for formatted or unformatted I/O. Note
that it is possible for both of them to return "YES". It
is also allowed for them to return "UNKNOWN", which means
that you can't count on them to be definitive.
On unix systems, there basically is not a reliable method to
tell. The operating system doesn't keep track of such things.
All you (or the compiler runtimes) can do is look at the contents
of the file to see if it look plausible as formatted or
unformatted. But this isn't infallable. It is possible to
write *ANY* content to the file with unformatted direct access
I/O - this includes content that might look a lot like some
other form (or might start out looking like some other form
and then change half-way through the file).
So, no, there is no completely portable, infallable way. But
you can often do well enough if you have some independent
data about the possible file content and organizations.
--
Richard Maine
ma...@qnet.com
> On unix systems, there basically is not a reliable method to
> tell. The operating system doesn't keep track of such things.
> All you (or the compiler runtimes) can do is look at the contents
> of the file to see if it look plausible as formatted or
> unformatted. But this isn't infallable. It is possible to
> write *ANY* content to the file with unformatted direct access
> I/O - this includes content that might look a lot like some
> other form (or might start out looking like some other form
> and then change half-way through the file).
Two months ago we had a question on the egcs mailing list from a user moving
unformatted sequential files between an SGI running IRIX and a PC running
Linux; hence he ran into an endianness problem (apart from that, the formats
are the same). For maximum confusion among the C++ crowd [what do you mean:
format of an unformatted file ?], I advised him to run the following program
to change endianness:
PROGRAM CONVRT
INTEGER N1, N2
OPEN(1,FORM='UNFORMATTED',ACCESS='DIRECT',RECL=4)
OPEN(2,FORM='UNFORMATTED',ACCESS='DIRECT',RECL=4)
I = 1
10 READ(1,REC=I,ERR=20) N1
N2 = N1 / 2**24 + MOD(N1 / 2**16, 2**8) * 2**8 +
+ MOD(N1 / 2**8, 2**8) * 2**16 + MOD(N1, 2**8) * 2**24
WRITE(2,REC=I) N2
I = I + 1
GOTO 10
20 CLOSE(1)
CLOSE(2)
END
As far as I can see this is completely Standard ('77) conforming - except
perhaps for the assumptions on the unit of record length and that reading
"beyond" the length of the file would make the direct access read fail :-)
Share and enjoy !
--
Toon Moene (mailto:to...@moene.indiv.nluug.nl)
Saturnushof 14, 3738 XG Maartensdijk, The Netherlands
Phone: +31 346 214290; Fax: +31 346 214286
g77 Support: mailto:for...@gnu.org; egcs: mailto:egcs...@cygnus.com
Are compilers smart enough to replace all of the 2**N expressions
with the actual values, or would the above code run faster if
the replacements were done by hand (eg. 256 instead of 2**8)?
I've seen the equivalent code in C, where the binary shift and
& operators are used in place of the exponentiation and integer
division above, and the code runs fast. Is the above code as fast
as the equivalent C code if compiled with modern Fortran compilers?
Cheers,
Robert Komar Physics Dept., Univ. of British Columbia, Canada
(stationed at the Sudbury Neutrino Observatory)
My mail address can be got from the following Unix command:
echo 'robkviaphysicsZubcZca' | tr 'Z' '.' | sed 's/via/@/'
> I wrote:
> : N2 = N1 / 2**24 + MOD(N1 / 2**16, 2**8) * 2**8 +
> : + MOD(N1 / 2**8, 2**8) * 2**16 + MOD(N1, 2**8) * 2**24
> Are compilers smart enough to replace all of the 2**N expressions
> with the actual values, or would the above code run faster if
> the replacements were done by hand (eg. 256 instead of 2**8)?
I wouldn't know about compilers in general, but given that I wrote the
following bug report to g77-alpha on Sat, 7 Nov 92 15:14:06 MET:
<QUOTE>
In converting the bitstream to floating point values for the meteorological
'fields', use is made of the following formula:
PVAL = ISIGN*2.**(-24)*KMANT*16.**(IEXP-64)
with the obvious assignments to ISIGN, KMANT & IEXP.
The reason this results in PVAL=0.0 everywhere is that 2.**(-24)
is bluntly replaced by 0.0. (Perusal of the assembly output from the
following program will convince you of this:
program try
print *, 2.**(-24)
end
)
Clearly this hints at a bug in the constant expression evaluation (constant
folding) code. It took me some time to find the culprit, but it seems to be
the routine [...]
</QUOTE>
it's clear that constant folding involving exponentiation has been in g77
from day -1 :-)
[snip]
> 10 READ(1,REC=I,ERR=20) N1
> N2 = N1 / 2**24 + MOD(N1 / 2**16, 2**8) * 2**8 +
> + MOD(N1 / 2**8, 2**8) * 2**16 + MOD(N1, 2**8) * 2**24
> WRITE(2,REC=I) N2
[snip]
A much simpler way of doing this is
character*1 bytes(4)
.
.
read(1,..) bytes
write(2,..) (bytes(k),k=4,1,-1)
.
.
If you need the upended numbers for use in the program reading the stuff,
then a 4-element, 1-byte array equivalenced to a real*4 or integer*4
variable lets you drop the bytes in place. Or "transfer" in F90. Or, in
F77 with the bit-twiddling extensions, AND.
Ken Plotkin
> In article <70g3da$jfs$1...@newnews.nl.uu.net>,
> I wrote:
> [snip]
> > 10 READ(1,REC=I,ERR=20) N1
> > N2 = N1 / 2**24 + MOD(N1 / 2**16, 2**8) * 2**8 +
> > + MOD(N1 / 2**8, 2**8) * 2**16 + MOD(N1, 2**8) * 2**24
> > WRITE(2,REC=I) N2
> [snip]
> A much simpler way of doing this is
> character*1 bytes(4)
> .
> .
> read(1,..) bytes
> write(2,..) (bytes(k),k=4,1,-1)
> .
> .
> If you need the upended numbers for use in the program reading the stuff,
> then a 4-element, 1-byte array equivalenced to a real*4 or integer*4
> variable lets you drop the bytes in place. Or "transfer" in F90. Or, in
> F77 with the bit-twiddling extensions, AND.
Well, the nice thing about your example is that it has one assumption less
than my code (which "knows" that INTEGERs are 4 bytes wide).
The other two assumptions still apply though: OPEN(...,RECL=4,...) means "4
byte record length" and READ(...,REC=I,END=20) bytes indeed jumps to label 20
on exceeding the length of the file.
[ Note that all of this only works if the information in the records is of
length 4 bytes as well - but I had that checked with the original
requester ]
>Well, the nice thing about your example is that it has one assumption less
>than my code (which "knows" that INTEGERs are 4 bytes wide).
I'm also assuming 4 byte integers. Both methods are easy to change for 2
byte integers.
Both methods will work if the data in the file is real*4.
>The other two assumptions still apply though: OPEN(...,RECL=4,...) means "4
>byte record length" and READ(...,REC=I,END=20) bytes indeed jumps to label 20
>on exceeding the length of the file.
Need to watch out for systems where RECL is in units of 4-byte words,
rather than bytes.
But the real thing to be fearful of is that somebody will enter this
thread with a demand for a 100% portable solution. :-)
Ken Plotkin