Direct file access in FORTRAN 77

I’m trying to read a binary file in FORTRAN 77 with ACCESS='DIRECT', but unfortunately, without success. The example function opens a file in direct mode/unformatted, and tries to read all data byte by byte (in this case, each byte just into character A):

      CHARACTER    A
      CHARACTER*32 MSG
      INTEGER      ISTAT, NBYTES

      NBYTES = 1024

      OPEN (UNIT=10, ACCESS='DIRECT', ACTION='READ', FILE=PATH,
     &      FORM='UNFORMATTED', IOSTAT=ISTAT, RECL=NBYTES,
     &      STATUS='OLD')
      IF (ISTAT .NE. 0) RETURN

      DO 10 I = 1, NBYTES
      READ (10, IOSTAT=ISTAT, IOMSG=MSG, REC=I) A

      IF (ISTAT .NE. 0) THEN
        PRINT *, ISTAT, MSG
        CLOSE (10)
        RETURN
      END IF

   10 CONTINUE

      CLOSE (10) 

The file is 1024 bytes in size. The first byte is read successfully, but the second one always fails with error “non-existing record number” (5002).

Using ACCESS='STREAM' instead, which is not a FORTRAN 77 feature, it works:

      OPEN (UNIT=10, ACCESS='STREAM', ACTION='READ', FILE=PATH,
     &      FORM='UNFORMATTED', IOSTAT=ISTAT, STATUS='OLD')
      IF (ISTAT .NE. 0) RETURN

      DO 10 I = 1, NBYTES
      READ (10, IOSTAT=ISTAT, IOMSG=MSG) A
      IF (ISTAT .NE. 0) THEN
        PRINT *, ISTAT, MSG, I
        CLOSE (10)
        RETURN
      END IF

   10 CONTINUE

Does someone know what I’m doing wrong?

The RECL argument in the OPEN statement expects different values for reading and writing. In order to write a file, the whole data size must be given (in this case, 1024 bytes), while to read, the size of a single record (1 byte) has to be set.

The right solution is to use ACCESS=“STREAM”. FORTRAN 77 as a standard was deleted long ago, and I don’t know of any current compilers that are limited to what was in that spec. There is nothing wrong with using modern Fortran features.

1 Like

In fact, the sample code already uses a non-FORTRAN 77 feature: ISOMSG = MSG

Also note that the RECL attribute may have to specified as the number of “words” in stead of the number of bytes - depending on the compiler.

Your best bet is indeed ACCESS = “STREAM”

2 Likes

What does it mean to “delete a standard”?

I know, just added it for testing. I try to stick to FORTRAN 77 to be able to use f2c as a compiler, but I already regret it. For instance, array slicing was not introduced until Fortran 90. Therefore, I have to stick to the FORTRAN 66 way. Crazy.

1 Like

So, as you point above, use RECL=1 for reading.
BTW, the ACTION='READ' spec is also non-F77, AFAIR.

The technical ISO term is “cancels”. Each new standard has a sentence like this one in F2018:

" 1. This fourth edition cancels and replaces the third edition (ISO 1539-1:2010), which has been technically revised."

All old versions are serially cancelled by their replacements.

(ISO 1539-1:2010 was the formal name of the Fortran 2008 standard.)

1 Like

I see, thanks!