Silverfrost Forums

Welcome to our forums

Problem with ACCESS='DIRECT'

1 Apr 2009 9:16 #4384

Thear users. I have a lot my old programs witch were compiled under MS Fortran Power Station , Digital Visual Fortran etc. They all work ! I use binary files to write data to my hard disk to read them next time. I have attachem a siple code where I oped direct access binary file. I use it all my live without any problem. FTN95 makes exe file too but when I run the program the 'fort44' is not writen to disk and I have a RUN-TIME ERROR !!! with info that Error 90, File acces and properties are incompatibile 00401000 main [+0120]. I have the sme problam under 32 WindowsXP or 64 bit WindowsXP. The lenght o record is RECL=3624 and it shuld be appropriate to write WRITE(44) LW,LPC,IT,FR,RZg,POLE,NWE what I showed below:

      IMPLICIT REAL*8 (A-H,O-Z)

      COMMON/GEO/RZg(6),Fr(3,6),POLE(6)


      OPEN(44, FILE='FORT4',ACCESS='DIRECT',FORM='UNFORMATTED',
     *RECL=3624,STATUS='UNKNOWN')


      LW=9
      LPC=9
      IT=1
      NWE=9

      DO j=1,6
      DO i=1,3

      FR(i,j)=3.14*j*i !Doesn't mater what number

      ENDDO

      RZg(j)=3.14*j*i  !Doesn't mater what number
      POLE(j)=3.14*j*i

      ENDDO


      WRITE(44) LW,LPC,IT,FR,RZg,POLE,NWE

      CLOSE(44)

      END

Please help me to solve the probelm.

1 Apr 2009 10:54 #4385

You need a record number for direct access files. It is non-standard to omit the record number.

Either omit ACCESS='DIRECT' from the open statement, or include REC=1 in the write statement.

You appear to only require a FORM='UNFORMATTED' file access.

John

2 Apr 2009 5:58 #4386

Thank You for help again. WRITE(44,REC=1) works or worsk OPEN...without ACCESS='DIRECT' - thank you.

But if you could spread your answer to exaple below. To tell the truth I all my life don't exactly understand the record statement (I watched this statement in other examples). It is very usefull and it works (even in option WRITE(44) in other compilers than FTN95 that I asked about why it doesn't work in FTN95). I know that in COMMON statement I have to add all size the arrays (their sizez it is multiplication theris numbers for exaple for FF(9,9,2) its size is 9x9x2=162 etc. and add all together gives 540. Use it to SAVEDATA subroutine I have possibilities to write all COMMON blok and READ it in other porgram. Example.

      COMMON /GEst/FF(9,9,2),FP(9,18,2),Wg(9,2),STg(9,2,2),FFO(9,9,2)
c                     162   +  324     +  18    +  36   +  162=540

................................

      CALL SAVEDATA(FF,540)

...................................


C**************************************
      subroutine SAVEDATA(IA,N)
C***************************************
     IMPLICIT REAL *8(A-H,O-Z)
     DIMENSION IA(N)
     WRITE(1) IA
     RETURN
     END

...................................

But when I mentioned yesterday about example

      IMPLICIT REAL*8 (A-H,O-Z)
      COMMON/GEO/RZg(6),Fr(3,6),POLE(6)

      OPEN(44, FILE='FORT4',ACCESS='DIRECT',FORM='UNFORMATTED',
     *RECL=3624,STATUS='UNKNOWN')


      LW=9
      LPC=9
      IT=1
      NWE=9

      DO j=1,6
      DO i=1,3
      FR(i,j)=3.14*j*i !Doesn't mater what number
      ENDDO
      RZg(j)=3.14*j*i  !Doesn't mater what number
      ENDDO

      WRITE(44,REC=1) LW,LPC,IT,FR,RZg,POLE,NWE
      CLOSE(44)

      END

it works all my live but I can't calculate from where is the number RECL=3624 from ? I have tried to use something like this

      WRITE(44,REC=1) LW, LPC, IT,  FR , RZg,POLE,NWE
C                     2  + 2  + 2 +(3x6)+ 6 + 6 )+ 2 =38 ???

but it doesn't match to *RECL=3624 ? When I have only arrays it is simpler - I have to multiply size arrays - in below exaple where there are integers it dosn't work !

How to unravel the numbre *RECL=3624 ?

2 Apr 2009 8:55 #4387

I have menaged - solution below: SAVE DATA

IMPLICIT REAL*8 (A-H,O-Z)

      COMMON/GEO/RZg(6),Fr(3,6),POLE(6)
      DIMENSION NWE(3)
      INTEGER :: lenn

      INQUIRE (IOLENGTH=lenn) LW,LPC,IT,FR,RZg,POLE,NWE
C                                4 + 4 + 4+(3*6)*8+6*8+6*8+6*2=264

      PRINT*,lenn

      OPEN(4,FILE='FORT4',ACCESS='direct',
     *FORM='UNFORMATTED',status='unknown',RECL=lenn)


      LW=9
      LPC=9
      IT=9
      NWE=9

      DO j=1,6
      DO i=1,3
      FR(i,j)=3.14
      ENDDO
      RZg(j)=3.14
      ENDDO


      WRITE(4,rec=1) LW,LPC,IT,FR,RZg,POLE,NWE

      PRINT*,LW,LPC,IT,FR,RZg,POLE,NWE

      CLOSE(4)

      END

READ DATA

      IMPLICIT REAL*8 (A-H,O-Z)
      COMMON/GEO/RZg(6),Fr(3,6),POLE(6)
      DIMENSION NWE(3)

      OPEN(4,FILE='FORT4',ACCESS='direct',
     *FORM='UNFORMATTED',status='unknown',RECL=264)

      READ(4,rec=1) LW,LPC,IT,FR,RZg,POLE,NWE
      Print*,LW,LPC,IT,FR,RZg,POLE,NWE

      CLOSE(4)

      END
2 Apr 2009 11:04 #4389

A couple of comments:

  1. It is advisable to use a file unit number (say) greater than 9, as units 1,5,6,7 have had special status in the past. I always start from 11.
  2. DIRECT access is only needed when you have multiple records to access directly, so if you have only 1 record, you can use a binary format file.
  3. The definition of record length has changed, from being compiler defined with F77 (and before) to being defined in the fortran standard since F90. Record length only needs to be defined for direct access files. Direct access files have fixed length records, while unformatted binary files have the record length defined by each write.

I would suggest that you should only use an unformatted binary file. to open: OPEN(UNIT=44, FILE='FORT4', FORM='UNFORMATTED', status='unknown')

To read or write : WRITE (44) LW,LPC,IT,FR,RZg,POLE,NWE

Note that record length for DIRECT is in bytes, with real8 : 8 bytes and integer4 : 4 bytes. Any old pre F90 codes could have record length defined by a different method, typically the number of 4-byte variables.

John

3 Apr 2009 6:07 #4390

Thank you for reply . Of course I rewrite open unit grater that 10. I know it but it was my mistake whilie I was writing the post.

Your solution seems to the best I am going to check it. Because my program is large I need a few hours to corect it.

But why I generaly asking about solution refering to

OPEN(44,file='fort3',access='direct',form='unformatted',recl=3624,status='unknown')

I have old prgram which was written in 77 standard in 70' very old. That days there weren't hard discs there were tapes to gathering datas. Files in my program all are opened by direct accsess and during writing data there isn't record in comand write like WRITE(44,rec=1) only

WRITE (44)

Comand above is controled by

REWIND (44)

commands etc.

Many years I use DOS system with Microsoft PowerStation 1.0 Fortran (even 'PROFORT' compiler before) which accepted that old definitions. Tryig compilind raw code under FTN95 (even with FIX format ) I obtained errors. Generaly wrong lenght of record or even info that

REWRITE (44)

command is BANED ! to use with direct access file.

I use propably what you wrote (binary file). But I have to be carefully beacuse program is large and many times there is calling to read and write with other record and it is hard to rewrite it without any mistakes on the spot.

My question is that maybe FTN95 accepts old standard with obsolete command - for exaple some option while compilation. In this case I wouldn't rewrite my old programs at all.

3 Apr 2009 11:22 #4396

You should read ftn95 help on file I/O as I don't think you have been using direct access. Certainly tapes did not support direct access, but were sequential access binary files. All your examples of file access only appear to require sequential access. This does not require RECL=, as the recorde length for sequential access is defined with the write statement and can be variable. REWIND is not compatible with direct access, as you always access the DA file by refering to the record number, and not sequentially.

John

3 Apr 2009 4:19 #4401

Thak you, evrythink is ok. Sequential access binary files is what I need. All my examples work ! Thank you.

Please login to reply.