Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can Fortran read bytes directly from a binary file?

I have a binary file that I would like to read with Fortran. The problem is that it was not written by Fortran, so it doesn't have the record length indicators. So the usual unformatted Fortran read won't work.

I had a thought that I could be sneaky and read the file as a formatted file, byte-by-byte (or 4 bytes by 4 bytes, really) into a character array and then convert the contents of the characters into integers and floats via the transfer function or the dreaded equivalence statement. But this doesn't work: I try to read 4 bytes at a time and, according to the POS output from the inquire statement, the read skips over like 6000 bytes or so, and the character array gets loaded with junk.

So that's a no go. Is there some detail in this approach I am forgetting? Or is there just a fundamentally different and better way to do this in Fortran? (BTW, I also tried reading into an integer*1 array and a byte array. Even though these codes would compile, when it came to the read statement, the code crashed.)

like image 361
bob.sacamento Avatar asked Jul 19 '12 21:07

bob.sacamento


People also ask

How do I read a binary file in Fortran?

There is no extra header information in Fortran direct access binary files! With sequential unformatted files you get record control words, but direct IO unformatted files are as plain as they can be. Writing an 8 byte real to disk will give you a file with exactly these eight bytes.

How do I read a Fortran file in Python?

Consider using Fortran direct-access files or files from the newer Stream I/O, which can be easily read by numpy. fromfile . it may be simpler to use numpy. fromfile() depending on cases (as shown in StanleyR's answer).


1 Answers

Yes.

Fortran 2003 introduced stream access into the language. Prior to this most processors supported something equivalent as an extension, perhaps called "binary" or similar.

Unformatted stream access imposes no record structure on the file. As an example, to read data from the file that corresponds to a single int in the companion C processor (if any) for a particular Fortran processor:

USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT
INTEGER, PARAMETER :: unit = 10
CHARACTER(*), PARAMETER :: filename = 'name of your file'
INTEGER(C_INT) :: data
!***
OPEN(unit, filename, ACCESS='STREAM', FORM='UNFORMATTED')
READ (unit) data
CLOSE(unit)
PRINT "('data was ',I0)", data

You may still have issues with endianess and data type size, but those aspects are language independent.

If you are writing to a language standard prior to Fortran 2003 then unformatted direct access reading into a suitable integer variable may work - it is Fortran processor specific but works for many of the current processors.

like image 73
IanH Avatar answered Oct 07 '22 22:10

IanH