JCampbell <
campbel...@gmail.com> schrieb:
> On Saturday, February 26, 2022 at 6:17:07 AM UTC+11,
rgae...@gmail.com wrote:
>
>> If I understood correctly this time, by writing the whole array with
>> write(unit)vz
>> the total record is composed by 3 subrecords:
>> 1. the leading record marker, a 4 bytes integer with the number of bytes of the actual data
>> 2. the values of the data in binary form
>> 3. the trailing record marker, another integer of 4 bytes with the same value of the leading.
>> Correct?
>
> Yes, Fortran "unformatted" files consist of RECORDS. Each record
> is as you describe (up to records of 2^31 bytes).
> The important distinction is they are records, dressed in 3
> components : record size header / data / record size trailer.
In general.
> Most compilers have the record size header as size in bytes as
> a 4-byte integer, but not all.
In practice: Which ones don't?
gfortran used a "long int" (which meant that file formats were
different in 32-bit and 64-bit systems, which was clearly bad).
In 2006, this was changed as a 4-byte integer with a negative
value indicating continuation, following ifort's lead.
>The header is not defined.
Not by the standard.
>
> Fortran unformatted binary files are NOT portable between compilers or operating systems.
$ cat write.f90
program main
implicit none
open (10,file="tst.dat",form="unformatted",action="write")
write (10) sqrt(2.)
end program main
$ nagfor write.f90 && ./a.out && od -t x1 tst.dat
NAG Fortran Compiler Release 7.1(Hanzomon) Build 7101
[NAG Fortran Compiler normal termination]
0000000 04 00 00 00 f3 04 b5 3f 04 00 00 00
0000014
$ gfortran write.f90 && ./a.out && od -t x1 tst.dat
0000000 04 00 00 00 f3 04 b5 3f 04 00 00 00
0000014
and, on a POWER9 little-endian machine,
$ xlf write.f90 && ./a.out && od -t x1 tst.dat
** main === End of Compilation 1 ===
1501-510 Compilation successful for file write.f90.
0000000 04 00 00 00 f3 04 b5 3f 04 00 00 00
0000014
As long as you are sticking to record lengths below
2GiB-9 bytes, you should see no problem.
> (This is worse than the case of formatted text files between Dos /
> unix / linux OS)
Not really (IMHO).
> It can be very disappointing to find some compilers are different, which I regard as a failing of the standard.
> Just look at the myriad of data portability approaches that have been developed because of this failing of the many Fortran Standards to address data portability.
> Imagine if the standardised Fortran unformatted file format included some identification of the intrinsic data types in the header/footer.
> Unfortunately Fortran unformatted-files are just temporary files.
>
> Note:
> gFortran and iFort use a 4-byte header/footer to indicate the
> record size, (but what is size?)
Documented for both compilers, it's bytes.
> For large records, larger than 2^31 bytes, gFortran adopts "sub
> records" of smaller than 2^31 - 9 bytes(?) with special -ve record
> size header values.
> iFort might use a different approach for larger records and might use words instead of bytes for size.
I doesn't. This is also not an accident: When the current scheme
for gfortran was adopted, the implementor looked at existing
implementations and chose ifort's scheme, because it offered the
maximum flexibility for larger records and was compatible with
4-byte schemes adopted by other compilers as long as the record
length was small enough.
> Silverfrost FTN95 uses a 1-byte header/footer for records smaller
> than 256 bytes, then a 5-byte header/footer for larger records.
Interesting to see that they still are in business, haven't heard
from that compiler for a long time.
Googling a bit found for the actual format, it seems a rather
trivial matter to write a conversion program between the
two formats. However, there is a better solution.
> If only there was an adopted standard, unformatted files might
> be more portable !!
There is a way to generate portable unformatted files in Fortran,
and has been since the adoption of the Fortran 2003 standard:
Unformatted streams.
These are much like C's binary files, there is no record structure,
and you can read and write to your heart's content, and there is
no problem interchanging the data (unless you run into big/little
endian issues). Just be sure to remember that writes don't truncate :-)