|Fortran Programming Guide|
This chapter discusses the input/output features provided by Sun Fortran compilers.
Accessing Files From Within Fortran Programs
Data is transferred between the program and devices or files through a Fortran logical unit. Logical units are identified in an I/O statement by a logical unit number, a nonnegative integer from 0 to the maximum 4-byte integer value (2,147,483,647).
*can appear as a logical unit identifier. The asterisk stands for standard input file when it appears in a
READstatement; it stands for standard output file when it appears in a
A Fortran logical unit can be associated with a specific, named file through the
OPENstatement. Also, certain "preconnected" units are automatically associated with specific files at the start of program execution.
Accessing Named Files
FILE=specifier establishes the association of a logical unit to a named, physical file at runtime. This file can be pre-existing or created by the program. See the Sun FORTRAN 77 Language Reference Manual for a full discussion of the
FILE=specifier on an
OPENstatement 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 can be used to bring command-line arguments and environment variables into the program as character variables for use as file names in
OPENstatements. (See man page entries for
getenv(3F) for details; these and other useful library routines are also described in the Fortran Library Reference).
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
GETCWDto return the value of the
$HOMEenvironment variable, find the last non-blank in the string, and determine the current working directory:
CHARACTER F*128, FN*128, FULLNAME*128PRINT*, 'ENTER FILE NAME:'READ *, FFN = FULLNAME( F )PRINT *, 'PATH IS: ',FNENDCHARACTER*128 FUNCTION FULLNAME( NAME )CHARACTER NAME*(*), PREFIX*128C This assumes C shell.C Leave absolute path names unchanged.C If name starts with '~/', replace tilde with homeC directory; otherwise prefix relative path name withC path to current directory.IF ( NAME(1:1) .EQ. '/' ) THENFULLNAME = NAMEELSE IF ( NAME(1:2) .EQ. '~/' ) THENCALL GETENV( 'HOME', PREFIX )FULLNAME = PREFIX(:LNBLNK(PREFIX)) //& NAME(2:LNBLNK(NAME))ELSECALL GETCWD( PREFIX )FULLNAME = PREFIX(:LNBLNK(PREFIX)) //& '/' // NAME(:LNBLNK(NAME))ENDIFRETURNEND
Opening Files Without a Name
OPENstatement need not specify a name; the runtime system supplies a file name according to several conventions.
Opened as Scratch
OPENstatement 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
CLOSEstatement, unless (with
STATUS='KEEP'is specified in the
If the file has already been opened by the program, you can use a subsequent
OPENstatement to change some of the file's characteristics; for example,
FORM. In this case, you would specify only the file's logical unit number and the parameters to change.
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:
- Standard input is logical unit 5 (also Fortran 95 unit 100)
- Standard output is logical unit 6 (also Fortran 95 unit 101)
- Standard error is logical unit 0 (also Fortran 95 unit 102)
Typically, standard input receives input from the workstation keyboard; standard output and standard error display output on the workstation screen.
In all other cases where a logical unit number but no
FILE=name is specified on an
OPENstatement, a file is opened with a name of the form
fort.n, where n is the logical unit number.
Opening Files Without an
Use of the
OPENstatement 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
INQUIRE, 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
INQUIREstatement, they are created.
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.
However, there are several satisfactory ways to communicate file names to a Fortran program.
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
cat testarg.fCHARACTER outfile*40C Get first arg as output file name for unit 51CALL getarg(1,outfile)OPEN(51,FILE=outfile)WRITE(51,*) 'Writing to file: ', outfileENDdemo%
f77 -silent -o tstarg testarg.fdemo%
cat AnyFileNameWriting to file: AnyFileNamedemo%
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:
cat testenv.fCHARACTER outfile*40C Get $OUTFILE as output file name for unit 51CALL getenv('OUTFILE',outfile)OPEN(51,FILE=outfile)WRITE(51,*) 'Writing to file: ', outfileENDdemo%
f77 -silent -o tstenv testenv.fdemo%
setenv OUTFILE EnvFileNamedemo%
cat EnvFileNameWriting to file: EnvFileNamedemo%
getenv, care should be taken regarding leading or trailing blanks. (FORTRAN 77 programs can use the library function
LNBLNK; Fortran 95 programs can use the intrinsic function
TRIM.) Additional flexibility to accept relative path names can be programmed along the lines of the
FULLNAMEfunction in the example at the beginning of this chapter.
f77: Logical Unit Preattachment Using
The library routine
IOINITcan also be used with
f77to attach logical units to specific files at runtime.
IOINITlooks 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
IOINITfacility is not implemented for
Example: Associate physical files
test.outin the current directory to logical units 1 and 2:
First, set the environment variables.
cat ini1.fCHARACTER PRFX*8LOGICAL CCTL, BZRO, APND, VRBOSEDATA CCTL, BZRO, APND, PRFX, VRBOSE& /.TRUE.,.FALSE.,.FALSE., 'TST',.FALSE. /CALL IOINIT( CCTL, BZRO, APND, PRFX, VRBOSE )READ(1, *) I, B, NWRITE(2, *) I, B, NENDdemo%
With environment variables and
ini1.inpand writes to
cat ini1.inp12 3.14159012 6demo%
f77 -silent -o tstinit ini1.fdemo%
cat ini1.out12 3.14159 6demo%
IOINITis 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:
/src/ioinit.f, where <release> varies for each software release. (Contact your system adminstrator for details.)
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.
In this way, a program that reads standard input (unit 5) and writes to standard output (unit 6) or standard error (unit 0) can, by redirection (using
<, >, >>, >&, |, |&, 2>, 2>&1on the command line), read or write to any other named file.
This is shown in the following table:
csh/sh/kshRedirection and Piping on the Command Line
Standard input --read from mydata
myprog < mydata
myprog < mydata
Standard output --write (overwrite) myoutput
myprog > myoutput
myprog > myoutput
Standard output -- write/append to myoutput
myprog >> myoutput
myprog >> myoutput
Redirect standard error to a file
myprog >& errorfile
myprog 2> errorfile
Pipe standard output to input of another program
myprog1 | myprog2
myprog1 | myprog2
Pipe standard error and output to another program
myprog1 |& myprog2
myprog1 2>&1 | myprog2
See the csh, ksh,and sh man pages for details on redirection and piping on the command line.
f77: VAX / VMS Logical File Names
If you are porting from VMS FORTRAN to FORTRAN 77, the VMS-style logical file names in the
INCLUDEstatement are mapped to UNIX path names. The environment variable
LOGICALNAMEMAPPINGdefines the mapping between the logical names and the UNIX path name. If the environment variable
LOGICALNAMEMAPPINGis set and the
-xldcompiler options are used, the compiler interprets VMS logical file names on the
Each lname is a logical name, and each path is the path name of a directory (without a trailing /). All blanks are ignored when parsing this string. Any trailing
/nolistis stripped from the file name in the
INCLUDEstatement. Logical names in a file name are delimited by the first colon in the VMS file name. The compiler converts file names of the form:
Uppercase and lowercase are significant in logical names. If a logical name is encountered on the
INCLUDEstatement that was not specified by
LOGICALNAMEMAPPING, the file name is used unchanged.
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
OPENstatement for the file.
A logical record in a direct access file is a string of bytes of a length specified by the
WRITEstatements 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.
WRITEstatements have an extra argument,
REC=n, to specify the record number to be read or written.
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.
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 with the format
For formatted files, the size of the record written is determined by the
FORMATstatement. In the preceding example, the
FORMATstatement 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
FORMATstatement. In such a case, each subsequent record is given successive record numbers.
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.
Sun Workshop Fortran 95 and Fortran 77 extend the OPEN statement to allow declaration of a "binary" I/O file.
Opening a file with
FORM='BINARY'has roughly the same effect as
FORM='UNFORMATTED', except that no record lengths are embedded in the file. Without this data, there is no way to tell where one record begins, or ends. Thus, it is impossible to
FORM='BINARY'file, because there is no way of telling where to backspace to. A
'BINARY'file will read as much data as needed to fill the variables on the input list.
WRITEstatement: Data is written to the file in binary, with as many bytes transferred as specified by the output list.
READstatement: Data is read into the variables on the input list, transferring as many bytes as required by the list. Because there are no record marks on the file, there will be no "end-of-record" error detection. The only errors detected are "end-of-file" or abnormal system errors.
INQUIREon a file opened with
RECL= AND NEXTREC=
BACKSPACEstatement: Not allowed--returns an error.
ENDFILEstatement: Truncates file at current position, as usual.
REWINDstatement: Repositions file to beginning of data, as usual.
An internal file is an object of type
CHARACTERsuch as a variable, substring, array, element of an array, or field of a structured record. Internal file
READcan be from a constant character string. I/O on internal files simulates formatted
READand WRITE statements by transferring and converting data from one character object to another data object. No file I/O is performed.
When using internal files:
- The name of the character object receiving the data appears in place of the unit number on a
WRITEstatement. On a
READstatement, the name of the character object source appears in place of the unit number.
- A constant, variable, or substring object constitutes a single record in the file.
- With an array object, each array element corresponds to a record.
f77extends direct I/O to internal files. (The ANSI standard includes only sequential formatted I/O on internal files.) This is similar to direct I/O on external files, except that the number of records in the file cannot be changed. In this case, a record is a single element of an array of character strings.
- Each sequential
WRITEstatement starts at the beginning of an internal file.
Example: Sequential formatted read from an internal file (one record only):
cat intern1.fCHARACTER X*80READ( *, '(A)' ) XREAD( X, '(I3,I4)' ) N1, N2 ! This codeline reads the internal file XWRITE( *, * ) N1, N2ENDdemo%
f77 -silent -o tstintern intern1.fdemo%
12 9912 99demo%
Example: Sequential formatted read from an internal file (three records):
cat intern2.fCHARACTER LINE(4)*16 ! This is our "internal file"* 12341234DATA LINE(1) / ' 81 81 ' /DATA LINE(2) / ' 82 82 ' /DATA LINE(3) / ' 83 83 ' /DATA LINE(4) / ' 84 84 ' /READ( LINE,'(2I4)') I,J,K,L,M,NPRINT *, I, J, K, L, M, NENDdemo%
f77 -silent intern2.fdemo%
a.out81 81 82 82 83 83demo%
Example: Direct access read from an internal file (one record) (f77 only):
cat intern3.fCHARACTER LINE(4)*16 ! This is our "internal file"* 12341234DATA LINE(1) / ' 81 81 ' /DATA LINE(2) / ' 82 82 ' /DATA LINE(3) / ' 83 83 ' /DATA LINE(4) / ' 84 84 ' /READ ( LINE, FMT=20, REC=3 ) M, N20 FORMAT( I4, I4 )PRINT *, M, NENDdemo%
f77 -silent intern3.fdemo%
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
OPENstatement, it is possible to do I/O directly to tape.
It could be more efficient to use the
TOPEN()routines rather than Fortran I/O statements to do I/O on magnetic tape.
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. 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 (plus eight characters of overhead) cannot be bigger than the buffer size.
As long as this restriction is complied with, the I/O system does not write records that span physical tape blocks, writing short blocks when necessary. This representation of unformatted records is preserved (even though it is inappropriate for tapes) so that files can be freely copied between disk and tapes.
Since the block-spanning restriction does not apply to tape reads, files can be copied from tape to disk without any special considerations.
Tape File Representation
A Fortran data file is represented on tape by a sequence of data records followed by an
endfilerecord. 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 only exception is that Fortran does not write an unformatted record that spans blocks; thus, the size of the largest unformatted record is eight characters less than the block size.
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.
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
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.
The standard also says that a
REWINDstatement can be used to reposition the file. Consequently, after reaching end-of-file, you can backspace over the end-of-file record and further manipulate the file--for example, writing more records at the end, rewinding the file, and rereading or rewriting it.
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.
To access a file on a tape with multiple files, first use the
mt(1) utility to position the tape to the needed file. Then open the file as a no-rewind magnetic tape such as
/dev/nrmt0. Referencing the tape with this name prevents it from being repositioned when it is closed. By reading the file until end-of-file and then reopening it, a program can access the next file on the tape. Any program subsequently referencing the same tape can access it where it was last left, preferably at the beginning of a file, or past the end-of-file record.
However, if your program terminates prematurely, it may leave the tape positioned anywhere. Use the SunOSTM operating system command
mt(1) to reposition the tape appropriately.
Fortran 95 I/O Considerations
Sun WorkShop 6 Fortran 95 and Fortran 77 are I/O compatible. Executables containing intermixed
f95compilations can do I/O to the same unit from both the
f95parts of the program.
However, Fortran 95 provides some additional features:
ADVANCE='NO'enables nonadvancing I/O, as in:
write(*,'(a)',ADVANCE='NO') 'Enter size= 'read(*,*) n
f95allows the group name to be preceded by
&on input. The Fortran 95 standard accepts only
&and this is what a
$as the symbol terminating an input group unless the last data item in the group is
CHARACTER, in which case the
$is treated as input data.
NAMELISTinput to start in the first column of a record.
DECODEare recognized and implemented by
f95just as they are by
Sun Microsystems, Inc.
Copyright information. All rights reserved.
|Library | Contents | Previous | Next | Index|