Fortran Input/Output |
2 |
![]() |
The character * may appear as a logical unit identifier. The asterisk stands for standard input file when it appears in a
READ
statement; it stands for standard output file when it appears in a WRITE
or PRINT
statement.A Fortran logical unit can be associated with a specific, named file through the
OPEN
statement. Also, certain "preconnected" units are automatically associated with specific files at the start of program execution.
OPEN
statement's FILE=
specifier establishes the association of a logical unit to a named, physical file at runtime. This file may be pre-existing or created by the program. See the Sun Fortran 77 Language Reference for a full discussion of the OPEN
statement. The
FILE=
specifier on an OPEN
statement may specify a simple file name (FILE=
'myfile.out
') or a file name preceded by an absolute or relative directory path (FILE=
'../Amber/Qproj/myfile.out
'). Also, the specifier may be a character constant, variable, or character expression.Library routines
GETARG(
argnumber,
charvalue)
and GETENV(
envar,
charvalue)
can be used to bring command-line arguments and environment variables respectively into the program as character variables that can be used as file names in OPEN
statements. (See man page entries for getarg(3F) and getenv(3F) for details).The following example (GetFilNam.f) shows one way to construct an absolute path file name from a typed-in name. The program uses the library routines
GETENV
, LNBLNK
, and GETCWD
to return the value of the $HOME
environment variable, find the last non-blank in the string, and determine the current working directory:
Compiling and running GetFilNam.f results in:
demo% pwd /home/users/auser/subdir demo% f77 -silent -o getfil GetFilNam.f demo% getfil anyfile /home/users/auser/subdir/anyfile demo% |
Opening Files Without a Name
The OPEN
statement need not specify a name; the runtime system supplies a file name according to several conventions. Opened as Scratch
Specifying STATUS='SCRATCH'
in the OPEN
statement opens a file with a name of the form tmp.FAAAxnnnnn -- where nnnnn is replaced by the current process ID, AAA is a string of three characters, and x is a letter; the AAA and x make the file name unique. This file is deleted upon termination of the program or execution of a CLOSE
statement, unless STATUS='KEEP'
is specified in the CLOSE
statement. Already Open
If the file has already been opened by the program, you can use a subsequent OPEN
statement to change some of the file's characteristics - specifically, BLANK
and FORM
. In this case, you would specify only the file's logical unit number and the parameters to change. Preconnected Units
Three unit numbers are automatically associated with specific standard I/O files at the start of program execution. These preconnected units are standard input, standard output, and standard error. For Fortran 77:
In all other cases where a logical unit number but no
FILE=
name is specified on an OPEN
statement, a file is opened with a name of the form fort.n, where n is the logical unit number.
OPEN
Statement
OPEN
statement is optional in those cases where default conventions can be assumed. If the first operation on a logical unit is an I/O statement other than OPEN
, the file fort.n is referenced, where n is the logical unit number (except for 0, 5, and 6, which have special meaning). These files need not exist before program execution. If the first operation on the file is not an
OPEN
or INQUIRE
statement, they are created.Example: If the
WRITE
in the code below is the first I/O statement issued on unit 25, the file fort.25 is created:
demo% cat TestUnit.f IU=25 WRITE( IU, '(I4)' ) IU END demo% |
demo% f77 -silent -o testunit TestUnit.f demo% testunit demo% cat fort.25 25 demo% |
Passing File Names to Programs
The file system does not have any automatic facility to associate a logical unit number in a Fortran program with a physical file. Via Runtime Arguments and GETARG
The library routine getarg(3F) can be used to read the command-line arguments at runtime into a character variable. The argument is interpreted as a file name and used in the OPEN
statement FILE=
specifier:
Via Environment Variables and GETENV
Similarly, the library routine getenv(3F) can be used to read the value of any environment variable at runtime into a character variable that in turn is interpreted as a file name:
Note that when using getarg or getenv, care should be taken regarding leading or trailing blanks. Additional flexibility to accept relative path names can be programmed along the lines of the FULLNAME function in the example at the beginning of this chapter.
Logical Unit Preattachment Using IOINIT (f77 Only)
The library routine IOINIT can also be used with f77 to attach logical units to specific files at runtime. IOINIT
looks in the environment for names of a user-specified form and then opens the corresponding logical unit for sequential formatted I/O. Names must be of the general form PREFIXnn, where the particular PREFIX is specified in the call to IOINIT, and nn is the logical unit to be opened. Unit numbers less than 10 must include the leading 0. See the Sun Fortran Library Reference, and the IOINIT(3F) man page. (The IOINIT facility is not implemented for f90.)
demo$ TST01=ini1.inp demo$ TST02=ini1.out demo$ export TST01 TST02 |
demo% setenv TST01 ini1.inp demo% setenv TST02 ini1.out |
The program ini1.f reads 1 and writes 2:
With environment variables and ioinit, ini1.f reads ini1.inp and writes to ini1.out:
demo% cat ini1.inp 12 3.14159012 6 demo% f77 -silent -o tstinit ini1.f demo% tstinit demo% cat ini1.out 12 3.14159 6 demo% |
IOINIT is adequate for most programs as written. However, it is written in Fortran specifically to serve as an example for similar user-supplied routines. Retrieve a copy from the following file, a part of the Fortran 77 package installation: /opt/SUNWspro/SC4.2/src/ioinit.f
Command-Line I/O Redirection and Piping
Another way to associate a physical file with a program's logical unit number is by redirecting or piping the preconnected standard I/O files. Redirection or piping occurs on the runtime execution command.
This is shown in Table 2-1:
See the csh and sh man pages for details on redirection and piping on the command-line.
VAX / VMS Logical File Names (f77 Only)
If you are porting from VMS FORTRAN to Fortran 77, the VMS-style logical file names in the INCLUDE statement are mapped to UNIX path names. The environment variable LOGICALNAMEMAPPING defines the mapping between the logical names and the UNIX path name. If the environment variable LOGICALNAMEMAPPING is set and the -xl or -xld compiler options are used, the compiler interprets VMS logical file names on the INCLUDE statement.
"lname1=path1; lname2=path2; ... " |
lname1:file |
path1/file |
Uppercase and lowercase are significant in logical names. If a logical name is encountered on the INCLUDE statement that was not specified by LOGICALNAMEMAPPING, the file name is used unchanged.
Direct I/O
Direct or random I/O allows you to access a file directly by record number. Record numbers are assigned when a record is written. Unlike sequential I/O, direct I/O records can be read and written in any order. However, in a direct access file, all records must be the same fixed length. Direct access files are declared with the ACCESS='DIRECT'
specifier on the OPEN
statement for the file.OPEN
statement's RCL=
specifier. READ
and WRITE
statements must not specify logical records larger than the defined record size. (Record sizes are specified in bytes.) Shorter records are allowed. Unformatted, direct writes leave the unfilled part of the record undefined. Formatted, direct writes cause the unfilled record to be padded with blanks.READ
and WRITE
statements have an extra argument, REC=
n, to specify the record number to be read or written.
OPEN( 2, FILE='data.db', ACCESS='DIRECT', RECL=200, & FORM='UNFORMATTED', ERR=90 ) READ( 2, REC=13, ERR=30 ) X, Y |
This program opens a file for direct access, unformatted I/O, with a fixed record length of 200 bytes, then reads the thirteenth record into
X
and Y
.
OPEN( 2, FILE='inven.db', ACCESS='DIRECT', RECL=200, & FORM='FORMATTED', ERR=90 ) READ( 2, FMT='(I10,F10.3)', REC=13, ERR=30 ) A, B |
This program opens a file for direct access, formatted I/O, with a fixed record length of 200 bytes. It then reads the thirteenth record and converts it to the format(I10,F10.3).
FORMAT
statement. In the preceding example, the FORMAT
statement defines a record of 20 characters or bytes. More than one record can be written by a single formatted write if the amount of data on the list is larger than the record size specified in the FORMAT
statement. In such a case, each subsequent record is given successive record numbers.
OPEN( 21, ACCESS='DIRECT', RECL=200, FORM='FORMATTED') WRITE(21,'(10F10.3)',REC=11) (X(J),J=1,100) |
The write to direct access unit 21 creates 10 records of 10 elements each (since the format specifies 10 elements per record) these records are numbered 11 through 20.
Internal Files
An internal file is an object of type CHARACTER
such as a variable, substring, array, element of an array, or field of a structured record. Internal file READ
s can be from a constant character string. I/O on internal files simulates formatted READ
and WRITE
by transferring and converting data from one character object to another data object. No physical I/O is actually performed.
WRITE
statement. On a READ
statement, the name of the character object source appears in place of the unit number.
Example: Sequential formatted read from an internal file (three records):
Example: Direct access read from an internal file (one record) (f77 only):
Tape I/O
Most typical Fortran I/O is done to disk files. However, by associating a logical unit number to a physically mounted tape drive via the OPEN
statement, it is possible to do I/O directly to tape. Using TOPEN Routines
With the nonstandard tape I/O package (see TOPEN (3F)) you can transfer blocks between the tape drive and buffers declared as Fortran character variables. You can then use internal I/O to fill and empty these buffers. This facility does not integrate with the rest of Fortran I/O and even has its own set of tape logical units. Refer to the man pages for complete information. Fortran Formatted I/O for Tape
The Fortran I/O statements provide facilities for transparent access to formatted, sequential files on magnetic tape. (With f77, the tape block size can be optionally controlled by the OPEN
statement FILEOPT
parameter.) There is no limit on formatted record size, and records may span tape blocks. Fortran Unformatted I/O for Tape
Using the Fortran I/O statements to connect a magnetic tape for unformatted access is less satisfactory. The implementation of unformatted records implies that the size of a record (+ eight characters of overhead) cannot be bigger than the buffer size. Tape File Representation
A Fortran data file is represented on tape by a sequence of data records followed by an endfile record. The data is grouped into blocks, with maximum block size determined when the file is opened. The records are represented in the same way as records in disk files -- formatted records are followed by newlines; unformatted records are preceded and followed by character counts. In general, there is no relation between Fortran records and tape blocks; that is, records can span blocks, which can contain parts of several records. The dd Conversion Utility
An end-of-file record in Fortran maps directly into a tape mark. In this respect, Fortran files are the same as tape system files. But since the representation of Fortran files on tape is the same as that used in the rest of UNIX, naive Fortran programs cannot read 80-column card images on tape. If you have an existing Fortran program and an existing data tape to read with it, translate the tape using the dd(1) utility, which adds newlines and strips trailing blanks.
demo% dd if=/dev/rmt0 ibs=20b cbs=80 conv=unblock | ftnprg |
The getc Library Routine
As an alternative to dd, you can call the getc(3F) library routine to read characters from the tape. You can then combine the characters into a character variable and use internal I/O to transfer formatted data. See also TOPEN(3F). End-of-File
The end-of-file condition is reached when an end-of-file record is encountered during execution of a READ statement. The standard states that the file is positioned after the end-of-file record. In real life, this means that the tape read head is poised at the beginning of the next file on the tape. Although it seems as if you could read the next file on the tape, this is not strictly true, and is not covered by the ANSI FORTRAN 77 Language Standard. Using Multifile Tapes
The name used to open the tape file determines certain characteristics of the connection, such as the recording density and whether the tape is automatically rewound when opened and closed.
Fortran 90 I/O Considerations
Fortran 90 1.2 and Fortran 77 4.2 use different I/O libraries. However, this should be transparent to the user. Executables containing intermixed f77 and f90 compilations can do I/O to the same unit from both the f77 and f90 parts of the program.