Silverfrost Forums

Welcome to our forums

Runtime Error 95: Direct Access Index Exception

16 Feb 2010 3:57 #5999

I am trying to correct an Direct Access Error in my Fortran 95 application (I am using FTN95 Express). I was able to correct the error in debug mode and when using a sample application with a release build but when using it combined with the system that is required for testing it fails with the 95: Direct Access Error exception. Where it is failing the Status of the file is 'REPLACE', should I be using a different status setting?

yours sincerely

Craig Hoy

2 Mar 2010 11:23 #6062

I am still experiencing problems with direct access and have attempted numerous status alternatives 'UNKNOWN', 'MODIFY', 'NEW' & 'APPEND' and stipulated 'Unformatted' as the FORM alternative without any luck. Does anyone have any ideas? :?

yours sincerely

Craig Hoy

3 Mar 2010 8:46 #6064

This is the open statement I use.

      OPEN ( UNIT   = Unit_Use(LUNIT),              &       !  fortran unit number
             FILE   = TREE_NAME,                    &
             STATUS = 'UNKNOWN',                    &
             ACCESS = 'DIRECT',                     &
             FORM   = 'UNFORMATTED',                &
             ACTION = 'READWRITE',                  &
             RECL   = Rec_Len*4,                    &       !  RECL is bytes
             IOSTAT = IOSTAT )

Most of these options are default, so I am puzzled why you are having so much trouble. ACCESS = 'DIRECT' and RECL = byte_Len must be provided. STATUS = 'UNKNOWN' is always the safest option.

3 Mar 2010 10:09 #6071

Unfortunately I was using the ACCESS='DIRECT', FORM='UNFORMATTED' and STATUS='UNKNOWN' so I am sorry to say that the reply didn't help.

Could someone else try to help? 😢

yours sincerely

Craig Hoy

3 Mar 2010 10:54 #6072

RECL = byte_Len must also be provided. You should report the value of IOSTAT and the message.

      integer*4 iostat 
      character MESSAGE*128 
      INTEGER*2 ERROR_NUMBER 
! 
      if (iostat /= 0) then 
         error_number = iostat 
         call FORTRAN_ERROR_MESSAGE@ (error_number, MESSAGE) 
         write (*,*) 'IOSTAT =',iostat, ' ', TRIM (MESSAGE) 
      end if 

Otherwise start looking at the attributes of the file you are trying to access, because I'd be reasonably confident the problem is not with the OPEN statement. Do you have the required rights in the directory you are accessing ?

3 Mar 2010 11:38 #6073

The following is a test program that works on my PC

      character tree_name*35, MESSAGE*128 
      integer*4 unit_use, rec_len, iostat, i, j
      integer*4 rec(77)
      INTEGER*2 ERROR_NUMBER 
      real*4    x
! 
      unit_use  = 21
      tree_name = 'c:\\tmp\\test.bin'
      rec_len   = size (rec)
!
      write (*,*) 'opening file'
      OPEN ( UNIT   = Unit_Use,            &       !  fortran unit number 
             FILE   = TREE_NAME,           & 
             STATUS = 'UNKNOWN',           & 
             ACCESS = 'DIRECT',            & 
             FORM   = 'UNFORMATTED',       & 
             ACTION = 'READWRITE',         & 
             RECL   = Rec_Len*4,           &       !  RECL is bytes 
             IOSTAT = IOSTAT ) 
!
!z      if (iostat /= 0) then 
         error_number = iostat 
         call FORTRAN_ERROR_MESSAGE@ (error_number, MESSAGE) 
         write (*,*) 'IOSTAT =',iostat, ' ', TRIM (MESSAGE) 
!z      end if 
!
      write (*,*) 'writing records'
      do i = 1,15
         rec = i
         write (unit=unit_use, rec=i, iostat=iostat) rec 
         error_number = iostat 
         call FORTRAN_ERROR_MESSAGE@ (error_number, MESSAGE) 
         write (*,*) 'RECORD =',i,' IOSTAT =',iostat, ' ', TRIM (MESSAGE) 
      end do
      write (*,*) 'File ',trim(tree_name),' should be',15*rec_len*4,' bytes long'
!
      write (*,*) 'reading records'
      do i = 1,10
         call random_number (x)
         j = int (x*15.) + 1
         rec = 0
         read (unit=unit_use, rec=j, iostat=iostat) rec 
         error_number = iostat 
         call FORTRAN_ERROR_MESSAGE@ (error_number, MESSAGE) 
         write (*,*) 'RECORD =',j,' IOSTAT =',iostat, ' ', TRIM (MESSAGE) 
      end do
!
      end
5 Mar 2010 12:00 #6079

It is worth noting a couple of features of Salford's direct I/O. I'm not sure if they all comply to the standard.

  1. Records need not be written in order. When a new record is written beyond the end of the file, any skipped records are also written. I'm not sure if this is required by the standard. Unfortunately these missing records are not left out of a virtual file. In my previous example, the following change also works: write (,) 'writing records' mi = 0 do j = 1,15 call random_number (x) i = int (x150.) + 1 rec = i write (unit=unit_use, rec=i, iostat=iostat) rec error_number = iostat call FORTRAN_ERROR_MESSAGE@ (error_number, MESSAGE) write (,) 'RECORD =',i,' IOSTAT =',iostat, ' ', TRIM (MESSAGE) mi = max (mi,i) end do write (,) 'File ',trim(tree_name),' should be',mirec_len*4,' bytes long'

  2. records can be read randomly, including records that have not been explicitly written, but not beyond the last file record. I'm not sure what is in skipped records that were not written by a WRITE statement.

  3. These files can be very large (> 2gb), and not limited to 231 bytes. I think there is a limit of 231 records.

  4. Records on disk are of fixed size. Lahey allows 'records' longer than the defined record length to be written, overflowing into other records. I'm not sure if this is required by the standard.

  5. There is no record size header on these records. Setting the record length to 1 byte or 1 word (4 bytes) effectively gives a random access disk array of 2^31 records, 8gb in the case of a I*4 word size. It works but it can be slow!

  6. FORTRAN_ERROR_MESSAGE@ reports an unexpected message for IOSTAT = -1 or 0. Could this be changed?

I have found DIRECT I/O to be very useful for creating simple databases. I have also superimposed an 'Indexed, variable length record random I/O' library on this fixed length structure and it works very well.

John

Please login to reply.