



External Files These are often just called text files. Terminals and printers should always be
treated as formatted sequential files. Data files of this type can be created in a
variety of ways, for example by direct entry from the keyboard, or by using a text
editor. Some Fortran systems do not allow records to be longer than a normal line of
text, for example 132 characters. Unless a text file is pre-connected it must be opened
with an OPEN statement, but the FORM= and ACCESS= keywords are not needed as the
default values are suitable:
OPEN(UNIT=4, FILE='REPORT', STATUS='NEW')
All data transfers must be carried out under format control. There are two options
with files of this type: you can either provide your own format specification or use
list-directed formatting.
The attraction of list-directed I/O is that the Fortran system does the work, providing simple data transfers with little programming effort. They are specified by having an asterisk as the format identifier:
WRITE(UNIT=*, FMT=*)'Enter velocity: ' READ(UNIT=*, FMT=*, END=999) SPEED |
WRITE(UNIT=LP, FMT=*)' Box of',N,' costs ',PRICE |
Box of 12 costs 9.5000000
List-directed output is best avoided except to write simple messages and for
diagnostic output during program development. The rules for list-directed formatting
are covered in detail in section 10.10.
The alternative is to provide a format specification: this provides complete control over the data transfer. The previous example can be modified to use a format specification like this:
WRITE(UNIT=LP, FMT=55)'Box of',N,' costs ',PRICE 55 FORMAT(1X, A, I3, A, F6.2) |
Box of 12 costs 9.50
The format specification is provided in this case by a FORMAT statement: its label is
the format identifier in the WRITE statement. Other ways of providing format
specifications are described in section 10.6.
One unusual feature of input under control of a format specification is that each line of text will appear to be padded out on the right with an indefinite number of blanks irrespective of the actual length of the data record. This means that, among other things, it is not possible to distinguish between an empty record and one filled with blanks. If numbers are read from an empty record they will simply be zero.
Unformatted sequential files are often used as to transfer data from one program
to another. They are also suitable for scratch files, i.e. those used temporarily during
program execution. The only limit on the length of unformatted records is that set by
the operating system; most systems allow records to contain a few thousand data
items at least. The OPEN statement must specify the file format, but the default
access method is "sequential". Each READ or WRITE statement transfers one
unformatted record.
For example, these statements open an existing unformatted file and read two records from it:
OPEN(UNIT=15, FILE='BIN', STATUS='OLD', FORM='UNFORMATTED') READ(15) HEIGHT, LENGTH, WIDTH READ(15) ARRAYP, ARRAYQ |
BACKSPACE and REWIND statements may generally be used on all unformatted
sequential files.
Unformatted Direct-access Files
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:
|
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 END |
Stock is 123 widgets at 556.89 each
This program could be extended fairly easily to allow the contents of the record to be
updated as the stock changes.
Formatted direct-access files are slightly more portable than the unformatted
form because their record length is always measured in characters. Otherwise there is
little to be said for them. The OPEN statement must specify both ACCESS='DIRECT'
and FORM='FORMATTED' and each READ and WRITE statement must contain both
format and record-number identifiers. List-directed transfers are not permitted. If the
format specification requires more than one record to be used, these additional
records follow on sequentially from that specified by REC=. It is an error to try to
read beyond the end of a record, but an incompletely filled record will be padded out
with blanks.