Since direct-access files are readable only by machine, it seems sensible to use unformatted records to maximise efficiency. The OPEN statement must specify ACCESS='DIRECT' and also specify the record length. Unfortunately the units used to measure the length of a record are not standardised: some systems measure them in bytes, others in numerical storage units, i.e. the number of real or integer variables a record can hold (see section 5.1). This is a minor obstacle to portability and means that you may need to know how many bytes your machine uses for each numerical storage unit, although this is just about the only place in Fortran where this is necessary. Most systems will allow you to open an existing file only if the record length is the same as that used when the file was created.
Each READ and WRITE statement transfers exactly one record and must specify the number of that record: an integer value from one upwards. The record length must not be greater than that declared in the OPEN statement; if an output record is not completely filled the remainder is undefined.
To illustrate how direct-access files can be used, here is a complete program which allows a very simple data-base, such as a set of stock records, to be examined. Assuming that the record length is measured in numerical storage units of 4 bytes, the required record length in this case can be computed as follows:
|NAME||1 CHARACTER*10 variable||10 chars = 10 bytes.|
|STOCK||1 INTEGER variable||1 unit = 4 bytes|
|PRICE||1 REAL variable||1 unit = 4 bytes|
The total record length is 18 bytes or 5 numerical storage units (rounding up to the next integer).
PROGRAM DBASE1 INTEGER STOCK, NERR REAL PRICE CHARACTER NAME*10 *Assume record length in storage units holding 4 chars each. OPEN(UNIT=1, FILE='STOCKS', STATUS='OLD', $ ACCESS='DIRECT', RECL=5) 100 CONTINUE *Ask user for part number which will be used as record number. WRITE(UNIT=*,FMT=*)'Enter part number (or zero to quit):' READ(UNIT=*,FMT=*) NPART IF(NPART .LE. 0) STOP READ(UNIT=1, REC=NPART, IOSTAT=NERR) NAME, STOCK, PRICE IF(NERR .NE. 0) THEN WRITE(UNIT=*,FMT=*)'Unknown part number, re-enter' GO TO 100 END IF WRITE(*,115)STOCK, NAME, PRICE 115 FORMAT(1X,'Stock is',I4, 1X, A,' at ', F8.2, ' each') GO TO 100 ENDThe typical output record of the program will be of the form:
Stock is 123 widgets at 556.89 each