Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29280 Discussions

Reading C binary file from Fortran code

szaghi
Beginner
1,727 Views
I all,

I am trying to read a C binary (big_endian ordinated) file from a Fortran code.
First of all my open statement is:

open(unit=unit_file, file=file_name, convert='BIG_ENDIAN', access='STREAM', form='UNFORMATTED')

I have used the 'STREAM' access to avoid the reading of the header-trailer tags of the standard Fortran record. It is correct? I know that C binary file is usually composed by "non structured" record without header-trailer tags..., thus is the 'STREAM' access the correct way to read this kind of binary file?

Besides, I have a second problem. The binary file contains records with a size that is not a multiple of byte; e.g. a record can be of 12 bit that is not a multiple of byte. How can I read single bit by a 'read' instruction?

Thank for all suggestions!
Stefano
0 Kudos
4 Replies
TimP
Honored Contributor III
1,727 Views
You are correct that the STREAM facility is intended to process generic files, such as those produced by C. The assumption is that those are streams of bytes, not bits. The latter would make it highly hardware dependent, not to mention language dependent. It seems there is a contradiction between your assertion that the file is record oriented and your attempt to read it as a byte stream. If you mean that the records are written as C bit fields, you might be able to solve the problem, but you would have to find out how the original writing platform distributed the data among the bytes in the data file (possibly padding with unused bits at the end?).
BIG_ENDIAN refers to byte ordering of standard data types, such as int and double, not to bit fields.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,727 Views

To read non-multiple of 8 bits you must read through a filter. Input side reads raw data in units of bytes, output side in whatever units of bits you want (as well as performing any conversion you want). You write the filter.

Two 12-bit words are a multiple of 8 bits. It is not unusual to have a record of 12-bit A to D conversion data packed together into a larger record. Or five 7-bit ASCII characters packed into a 36-bit word with 1 bit ignored or used for other purpose (old PDP-10 data file on 1/2"mag tape).

Jim Dempsey
0 Kudos
szaghi
Beginner
1,727 Views

To read non-multiple of 8 bits you must read through a filter. Input side reads raw data in units of bytes, output side in whatever units of bits you want (as well as performing any conversion you want). You write the filter.

Two 12-bit words are a multiple of 8 bits. It is not unusual to have a record of 12-bit A to D conversion data packed together into a larger record. Or five 7-bit ASCII characters packed into a 36-bit word with 1 bit ignored or used for other purpose (old PDP-10 data file on 1/2"mag tape).

Jim Dempsey

Thank you very much (also to tim18). Probably tomorrow I will see the original C code thus I will have more details (at today I am basing only on the specifications of the records format)...
The writing of filter is intereresting: what do you mean with filter? How can I write a filter?
Thank you very much!
Stefano
0 Kudos
szaghi
Beginner
1,727 Views
Hi all,
I have some news... bad news, and I need your help.
I am successful (with the help of a wise-guy) in reading the C binary file (and this seems a good new), but only with the use of "fgetc" function from the portability module IFPORT (and this is the bad news). I need to replace the fgetc with "something" that is more fortran standard.
My last "deduction" is that the bit-fields are rounded to byte thus I don't need to read non-multiple of byte, but I still not have success to read the file without using fgetc.
I am almost sure that the file is written with 3 different "fprint" calls, writing 3 different "records" (the first 2 are ascii, while the last is not), but, because I don't know C, I am not sure if the file is a single "stream" of data or there is a "record-structure".
Basing on success obtained using fgetc function, do you have any idea to replace it with a more standard Fortran code?
Thank you for all your suggestions and explanations.
My best regards,
Stefano


0 Kudos
Reply