The READ statement obtains data from an external or internal file and transfers the data to internal storage. If you specify an input list, values transfer from the file to the data items you specify.
The WRITE statement transfers data from internal storage into an external or internal file.
The PRINT statement transfers data from internal storage into an external file. Specifying the -qport=typestmt compiler option enables the TYPE statement which supports functionality identical to PRINT. If you specify an output list and format specification, values transfer to the file from the data items you specify. If you do not specify an output list, the PRINT statement transfers a blank record to the output device unless the FORMAT statement it refers to contains, as the first specification, a character string edit descriptor or a slash edit descriptor. In this case, the records these specifications indicate transfer to the output device.
Execution of a WRITE or PRINT statement for a file that does not exist creates that file, unless an error occurs.
If an input/output item is a pointer, data transfers between the file and the associated target.
During advancing input from a file with a PAD= specifier that has the value NO, the input list and format specification must not require more characters from the record than that record contains. If the PAD= specifier has the value YES, blank characters are supplied if the input list and format specification require more characters from the record than the record contains.
If you want to pad files connected for sequential access, specify the -qxlf77=noblankpad compiler option. This compiler option also sets the default value for the PAD= specifier to NO for direct and stream files and YES for sequential files.
During nonadvancing input from a file with a PAD= specifier that has the value NO, an end-of-record condition occurs if the input list and format specification require more characters from the record than the record contains. If the PAD= specifier has the value YES, an end-of-record condition occurs and blank characters are supplied if an input item and its corresponding data edit descriptor require more characters from the record than the record contains. If the record is the last record of a stream file, an end-of-file condition occurs.
You can specify asynchronous READ and WRITE data transfer statements to initiate asynchronous data transfer. Execution continues after the asynchronous I/O statement, without waiting for the data transfer to complete. Executing a matching WAIT statement with the same ID= value that was returned to the ID= variable in the data transfer statement detects that the data transfer statement is complete, or waits for that data transfer statement to complete.
The data transfer of an I/O item in an asynchronous I/O statement can complete:
For information on situations where data transfer must complete during the asynchronous data transfer statement, see Implementation details of XL Fortran Input/Output.
If an error occurs during the execution of an asynchronous data transfer statement, the statement executes as if it were synchronous. The ID= specifier remains undefined and the accompanying WAIT statement does not execute. Instead of the WAIT statement, the ERR= specifier handles the error, and the IOSTAT= specifier indicates the status of the I/O operation.
You must not reference, define, or undefine variables or items associated with a variable appearing in an I/O list for an asynchronous data transfer statement, until the execution of the matching WAIT statement.
Any deallocation of allocatable objects and pointers and changing association status of pointers are disallowed between an asynchronous data transfer statement and the matching WAIT statement.
Multiple outstanding asynchronous data transfer operations
on the same unit must all be READ or all be WRITE. You must not specify other I/O statements
on the same unit until the matching WAIT statements
for all outstanding asynchronous data transfer operations on the same unit
execute. In the case of direct access, an asynchronous WRITE statement must not specify both the same unit and record number
as any asynchronous WRITE statement for which the matching WAIT statement has not been executed.
For stream access, an asynchronous WRITE statement must not specify
either the same unit and location within a file as any asynchronous WRITE statement for which the matching WAIT statement has not been
executed.
In the portion of the program that executes between the asynchronous data transfer statement and the matching WAIT statement, the integer_variable in the NUM= specifier or any variable associated with it must not be referenced, become defined, or become undefined.
In the portion of the program that executes between the asynchronous data transfer statement and the matching WAIT statement, you must not reference, define, or undefine variables or items associated with the integer_variable in the NUM= specifier of a READ or WRITE statement.
Using Asynchronous I/O
SUBROUTINE COMPARE(ISTART, IEND, ISIZE, A) INTEGER, DIMENSION(ISIZE) :: A INTEGER I, ISTART, IEND, ISIZE DO I = ISTART, IEND IF (A (I) /= I) THEN PRINT *, "Expected ", I, ", got ", A(I) END IF END DO END SUBROUTINE COMPARE PROGRAM SAMPLE INTEGER, PARAMETER :: ISIZE = 1000000 INTEGER, PARAMETER :: SECT1 = (ISIZE/2) - 1, SECT2 = ISIZE - 1 INTEGER, DIMENSION(ISIZE), STATIC :: A INTEGER IDVAR OPEN(10, STATUS="OLD", ACCESS="DIRECT", ASYNCH="YES", RECL=(ISIZE/2)*4) A = 0 ! Reads in the first part of the array. READ(10, REC=1) A(1:SECT1) ! Starts asynchronous read of the second part of the array. READ(10,ID=IDVAR, REC=2) A(SECT1+1:SECT2) ! While the second asynchronous read is being performed, ! do some processing here. CALL COMPARE(1, SECT1, ISIZE, A) WAIT(ID=IDVAR) CALL COMPARE(SECT1+1, SECT2, ISIZE, A) END
Advancing I/O positions the file after the last record that is read or written, unless an error condition occurs.
Nonadvancing I/O can position the file at a character position within the current record, or a subsequent record. With nonadvancing I/O, you can READ or WRITE a record of the file by a sequence of I/O statements that each access a portion of the record. You can also read variable-length records and inquire about the length of the records.
Nonadvancing I/O
! Reads digits using nonadvancing input INTEGER COUNT CHARACTER(1) DIGIT OPEN (7) DO READ (7,FMT="(A1)",ADVANCE="NO",EOR=100) DIGIT COUNT = COUNT + 1 IF ((ICHAR(DIGIT).LT.ICHAR('0')).OR.(ICHAR(DIGIT).GT.ICHAR('9'))) THEN PRINT *,"Invalid character ", DIGIT, " at record position ",COUNT STOP END IF END DO 100 PRINT *,"Number of digits in record = ", COUNT END ! When the contents of fort.7 is '1234\n', the output is: ! Number of digits in record = 4
For an explicit connection using an OPEN statement for sequential or stream I/O that specifies the POSITION= specifier, you can position the file explicitly at the beginning, at the end, where the position is on opening.
If the OPEN statement does not specify the POSITION= specifier:
After an implicit OPEN, the file position is at the beginning:
You can use a REWIND statement to position a file at the beginning. The preconnected units 0, 5 and 6 are positioned as they come from the parent process of the application.
The positioning of a file prior to data transfer depends on the method of access:
After advancing I/O data transfer, the file position is:
After nonadvancing input the file position:
If the file position is beyond the endfile record, a READ, WRITE, PRINT, or ENDFILE statement can not execute if the compiler option -qxlf77=softeof is not set. A BACKSPACE or REWIND statement can be used to reposition the file.
Use the -qxlf77=softeof option to be able to read and write past the end-of-file.
For formatted stream output with no errors, the terminal point of the file is set to the highest-numbered position to which data was transferred by the statement. For unformatted stream output with no errors, the file position is unchanged. If the file position exceeds the previous terminal point of the file, the terminal point is set to the file position. Use the POS= specifier with an empty output list to extend the terminal point of the file without writing data. After data transfer, if an error occurs, the file position is indeterminate.