HELP!! fread reads Fortran Direct files incorrectly 
Author Message
 HELP!! fread reads Fortran Direct files incorrectly

  Dear Netters,

        I am trying to read a fortran "direct" format data file using fseek()
  and fread() (in C). The records are 1024 bytes long. I am trying to read the
  6th record using the following code.

  unsigned char buff [1024];

  flptr = fopen (filename, "r");
  fseek (flptr, 1024 * 5, SEEK_SET);
  fread (buff, 1, 1024L, flptr);

  The output of the code is not what I expect. The bit ordering in the array
  buff is messed up when I compare the result with the data file (which I am
  viewing using a Hex Viewer).

  Could some kind soul point out any mistake that I am making ?

  - TAPAS



Sun, 09 Feb 1997 08:04:29 GMT  
 HELP!! fread reads Fortran Direct files incorrectly

Quote:


>Subject: HELP!! fread reads Fortran Direct files incorrectly
>Date: 24 Aug 1994 00:04:29 GMT
>Keywords: Fortran Direct Files, fread
>  Dear Netters,
>        I am trying to read a fortran "direct" format data file using fseek()
>  and fread() (in C). The records are 1024 bytes long. I am trying to read the
>  6th record using the following code.
>  unsigned char buff [1024];
>  flptr = fopen (filename, "r");
>  fseek (flptr, 1024 * 5, SEEK_SET);
>  fread (buff, 1, 1024L, flptr);
>  The output of the code is not what I expect. The bit ordering in the array
>  buff is messed up when I compare the result with the data file (which I am
>  viewing using a Hex Viewer).
>  Could some kind soul point out any mistake that I am making ?
>  - TAPAS

Which Fortran do you use ?
Several Fortrans use additional bytes within their direct access files. You
have to take care about it.

Robert



Sun, 09 Feb 1997 19:08:14 GMT  
 HELP!! fread reads Fortran Direct files incorrectly
Quote:

>  Dear Netters,

>    I am trying to read a fortran "direct" format data file using fseek()
>  and fread() (in C). The records are 1024 bytes long. I am trying to read the
>  6th record using the following code.

>  unsigned char buff [1024];

>  flptr = fopen (filename, "r");
>  fseek (flptr, 1024 * 5, SEEK_SET);
>  fread (buff, 1, 1024L, flptr);

                   ^^^^^^^^
                Here's your mistake, possibly.

Quote:

>  The output of the code is not what I expect. The bit ordering in the array
>  buff is messed up when I compare the result with the data file (which I am
>  viewing using a Hex Viewer).

>  Could some kind soul point out any mistake that I am making ?

>  - TAPAS

        Why are you specifying a LONG constant here?  Let the prototype
        do the work.  Then again, I guess you aren't using the prototype
        or else you have all of your warnings turned off because you should
        have received a compiler warning.

        Do yourself a favour, turn on all of your compiler warnings and
        use function prototypes so you see the warnings about this.

        The second point is perhaps you should try opening up with "rb".
        I *never* assume that the default is either binary or ASCII - I
        always state it explicitly.

        Finally, it is important to know what FORTRAN code was used to
        create the file.  You say it is direct access.  Ok, I guess it
        was created with ACCESS='DIRECT'.  But was the file opened up
        in ASCII or binary mode, i.e. FORM='FORMATTED' (ASCII) or
        FORM='UNFORMATTED' (sort of 'binary').  If it was ASCII, then
        perhaps you have some line delimiters after your records.  If
        it was 'UNFORMATTED', then it's wrong, wrong, wrong.  I never
        pass up a chance to dump on Microsoft language products so...

      Begin dump on Microsoft FORTRAN

        Microsoft FORTRAN has usurped the 'normal' meaning of 'unformatted'.
        To me, 'unformatted' means that a block of memory will be blasted out
        to a file as an 'unformatted' stream of bytes, i.e. if I do:
                real x(1000)
                write(1) (x(i),i=1,1000);
        then I should get an unbroken stream of 1000 float values, i.e.
        4000 bytes.  As far as I know, most FORTRANs do this.  Yes, they
        may add a few bytes in front of the 'record' (i.e. on a VAX),
        but they generally keep the stream contiguous.  Microsoft has
        chosen to break such a stream into 128-byte 'records' and as a
        result, it is a format which is proprietary and is unique to
        Microsoft's FORTRAN.  Without special considerations, you can't
        read such a file with any other language product (QBASIC, C, Pascal,
        etc).  It's a ticking time bomb for people who bring over their
        ANSI FORTRAN programs from other systems and then simply recompile
        with Microsoft FORTRAN.  Oh, sure they work just fine as long as
        you only read & write those files with that particular compiler.
        But it all breaks down when you try to use another language and
        possibly even other vendor's FORTRAN compilers.

        So anyway, evidently somebody realized their mistake in stealing
        this 'standard' keyword for their own purposes, because they then
        had to add a non-standard 'binary' open format which implements
        the file stream the way it should have been in the first place.

        I'm sure someone will point out that the ANSI committee doesn't
        specify what bytes are written, but I am more concerned about
        'reasonable expectations', not the 'freedom of interpretation'.
        If they wanted to implement such a proprietary format, Microsoft
        should have used 'unformatted' for the contiguous stream of
        bytes and then implemented that 128-byte record junk with their
        own extension to the standard, i.e.:
                open(,,,form='MICROSOFTBRAINDEADFORMAT',access=...)

      End dump on Microsoft FORTRAN (thank you, I feel much better now)

        Now, where was I.  Oh yeah, so if the file was created with
        'formatted', then you're out of luck - it's hopelessly corrupted.
        You can either change the FORTRAN program to use 'binary' instead
        of 'unformatted', or you can write another Microsoft FORTRAN
        program to open up the input file as 'formatted', read in the records
        and write them out to another output file as 'binary'.  Then you
        should be able to read the file ok and with the language of your
        choice.

        You can check the file format perhaps by checking the file size.
        If you know it contains 10 records of 1024, then the size should
        be 10240 bytes.  If it is more, then you know that the FORTRAN
        I/O kernel has split it into 128 byte blocks.

        We now return you to your regularly scheduled programming...
        (in C, that is...) :)
--

Airborne Geophysics
Geological Survey of Canada, Ottawa



Mon, 10 Feb 1997 06:54:50 GMT  
 HELP!! fread reads Fortran Direct files incorrectly

    Begin dump on Microsoft FORTRAN

       Microsoft FORTRAN has usurped the 'normal' meaning of 'unformatted'.
       To me, 'unformatted' means that a block of memory will be blasted out
       to a file as an 'unformatted' stream of bytes, i.e. if I do:
               real x(1000)
               write(1) (x(i),i=1,1000);
       then I should get an unbroken stream of 1000 float values, i.e.
       4000 bytes.  As far as I know, most FORTRANs do this.  Yes, they
       may add a few bytes in front of the 'record' (i.e. on a VAX),
       but they generally keep the stream contiguous.  Microsoft has
       chosen to break such a stream into 128-byte 'records' and as a
       result, it is a format which is proprietary and is unique to
       Microsoft's FORTRAN.

     End dump on Microsoft FORTRAN (thank you, I feel much better now)

Microsoft sure ain't perfect, but it sounds like they have a very good
copy of what was called RECFM=VS (as in record format is variable and
spanned - logical record broken into smaller physical records) on the
(expletive deleted) mainframe known as an IBM/360. If I recall, the VS
format was an almost exact copy of even older formats which were
in use with machines that had tape drives, but no disks! IBM was not the
only vendor who used the scheme, and the vendors tended to use it for all
of their languages, i.e. it was also usable by COBOL, PL/I, and other ABCs
like JOVIAL or SNOBOL. The undifferentiated stream of bytes is a UNIXism
that got mindlessly carried over into micros.

The problem which is being solved is "How long is the record?" so that it
is possible to read only the initial fields even when you don't know the
record length. Under the UNIXism, you need to know the record length to skip
the unwanted fields, while in file systems that keep a notion of records it
is possible to reliably get to the end of the record. Try backspacing when
you do not know the record length. DEC points out that RMS is the record
management system which can also handle an undifferentiated stream of bytes
if you care to ignore all of its services. RMS is more than just a file
system.

FORMATTED or UNFORMATTED have the same problem with record size, so I think
there is a certain amount of confusion between formatting of data as opposed
to record and file structure. If you want Microsoft to not use record
structure for sequential access, you can use their FORM=BINARY and get an
undifferentiated stream of bytes or you can use ACCESS=DIRECT and even throw
away the null padding.

Fortran I/O is based on a record model, and even the UNIX Fortrans support
record capabilities like backspace. C I/O is based on the undifferentiated
stream of bytes model (from UNIX) and naive users tend to get tripped up on
the visible (to C) record structure when they read Fortran output. Some are
just confused and others display their ignorance in public and blame the
vendors.

On this one, Microsoft does it right and you should RTFM and understand what
problem is being solved.



Mon, 10 Feb 1997 18:43:56 GMT  
 HELP!! fread reads Fortran Direct files incorrectly
|>
|>
|>   Dear Netters,
|>
|>         Thanks for all the responses ( microsoft flames :-) ) I got.
|>
|>         To sum up, let's assume the data file contained data 00 7E 00 7F in
|>   contiguous bytes. Using the code I posted, I ended up reading that data like
|>   this.
|>
|>         buff[0] = 00    buff[1] = 7F    buff[2] = 00    buff[3] = 7E
|>
|>         Now I read it like this
|>
|>         unsigned short buff[512];       \\ in windows unsigned short is
|>                                         \\ 2 bytes guaranteed
|>
|>         fread (buff, 2, 512, flptr);
|>        
|>   and it reads buff[0] = 7E00 and buff[1] = 7F00. I reverse the bytes (save
|>   my ***) and meet the deadline.
|>
|>         But how can I read it right ?
|>
|>         - TAPAS

You are running on a little endian machine.  What you describe is
'right' for such a machine.
--
| Chick Racer                     Chevron Petroleum Technology Co. |
| (713) 596-2430                  P.O. Box 42832                   |

| 4209 Hayes Rd.                                                   |



Tue, 11 Feb 1997 22:50:48 GMT  
 HELP!! fread reads Fortran Direct files incorrectly

  Dear Netters,

        Thanks for all the responses ( microsoft flames :-) ) I got.

        To sum up, let's assume the data file contained data 00 7E 00 7F in
  contiguous bytes. Using the code I posted, I ended up reading that data like
  this.

        buff[0] = 00    buff[1] = 7F    buff[2] = 00    buff[3] = 7E

        Now I read it like this

        unsigned short buff[512];       \\ in windows unsigned short is
                                        \\ 2 bytes guaranteed

        fread (buff, 2, 512, flptr);

  and it reads buff[0] = 7E00 and buff[1] = 7F00. I reverse the bytes (save
  my ***) and meet the deadline.

        But how can I read it right ?

        - TAPAS



Tue, 11 Feb 1997 20:23:05 GMT  
 HELP!! fread reads Fortran Direct files incorrectly

Quote:

>  Dear Netters,

>        Thanks for all the responses ( microsoft flames :-) ) I got.

>        To sum up, let's assume the data file contained data 00 7E 00 7F in
>  contiguous bytes. Using the code I posted, I ended up reading that data like
>  this.

>        buff[0] = 00    buff[1] = 7F    buff[2] = 00    buff[3] = 7E

        Well that doesn't look right, but *HOW* do you *KNOW* the file
        contains 0/7e/0/7f in a contiguous stream?  Don't go by how you
        wrote the file, what does it say in a hex dump?  If the file
        contains 'ABCD....' and you use fread() to read the file with
        a 'char' array, then you should get 'ABCD...' in the array.
        I still don't know if you are dealing with characters or
        integers.

Quote:
>        Now I read it like this

>        unsigned short buff[512];       \\ in windows unsigned short is
>                                        \\ 2 bytes guaranteed

>        fread (buff, 2, 512, flptr);

>  and it reads buff[0] = 7E00 and buff[1] = 7F00. I reverse the bytes (save
>  my ***) and meet the deadline.

>        But how can I read it right ?

>        - TAPAS

        Now I'm really confused.  Does the file contain character data
        or integers?  There's a big difference.  Was the file created
        on a PC or did you get it from another machine?  If you got
        it from the other machine, then you may need to be concerned
        with the byte order if you are treating the data as integers.
        Did you ever determine whether the file contained any padding
        or inter-record stuff?  Is the file size a multiple of 1024?

        It would help if you would re-post the problem with the following:

        (a) the variable declarations and write statements from the
            FORTRAN program that wrote the file

        (b) a hex dump of the first few bytes of the file (10 should be
            enough)

        (c) the variable declarations and fread() statements from the C
            program trying to read the file.

        and answer the following questions:
        (a) Was the file created on another machine? (i.e. is byte order
            a factor here).
        (b) What is the file size?  What is the record length (1024-byte
            fixed-length records?). Is the file size an exact multiple
            of the record length?
--

Airborne Geophysics
Geological Survey of Canada, Ottawa



Wed, 12 Feb 1997 00:14:04 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Please help: reading FORTRAN files using C code

2. need help reading fortran unformatted file from a c program

3. Help with Emulating a FORTRAN File Read Function in C

4. why does this fread fail, trying to read 100,000 rec in one fread

5. mixing fread and fscanf in reading binary file

6. Read a file using fread trouble

7. How do read a binary file, fread()?

8. ASCII file read vs. fseek()/fread()

9. : Reading full screen images from file using fread()?

10. reading fortran data file from C program

11. Writing binary files in C to be read in MS FORTRAN 4.0

12. read binary file written in fortran format

 

 
Powered by phpBB® Forum Software