インテル® Fortran コンパイラー 14.0 ユーザー・リファレンス・ガイド

Rules for Unformatted Sequential READ Statements

Unformatted, sequential READ statements transfer binary data (without translation) between the current record and the entities specified in the I/O list. Only one record is read.

Objects of intrinsic or derived types can be transferred.

For data transfer, the file must be positioned so that the record read is an unformatted record or an end-of-file record.

The unformatted, sequential READ statement reads a single record. Each value in the record must be of the same type as the corresponding entity in the input list, unless the value is real or complex.

If the value is real or complex, one complex value can correspond to two real list entities, or two real values can correspond to one complex list entity. The corresponding values and entities must have the same kind parameter.

If the number of I/O list items is less than the number of fields in an input record, the statement ignores the excess fields. If the number of I/O list items is greater than the number of fields in an input record, an error occurs.

If a statement contains no I/O list, it skips over one full record, positioning the file to read the following record on the next execution of a READ statement.

If the file is connected for formatted, list-directed, or namelist I/O, unformatted data transfer is prohibited.

You have previously been able to buffer the output (WRITEs) of variable length, unformatted, sequential files, by specifying certain values for an OPEN statement, environment variable, or compiler option. You can now do the same buffering for input (READs) of records. To enable buffering for the input of records, you can specify any of the following:

When any of the above are specified, the Fortran Runtime Library buffers all input records from variable length, unformatted, sequential files, regardless of the size of the records in the file.

Optimizing for Time or Space

When reading variable length, unformatted sequential records, the runtime system may optimize for time or for space.

This optimization decision is made during runtime on a record-by-record basis using specifications made by the program and the length of a given record. That is, one record may be optimized for time while another record from the same file may be optimized for space.

The default behavior when reading records of this type whose length exceeds the specified block size, is to not buffer the input records. You can override this default behavior by requesting that the input be buffered.

The following table shows the relationship between a file's specified block size and the length of its variable length records. Note that the length of the individual record is the key:

 

record length >= block size

record length < block size

buffering unspecified

Optimizes for space

Optimizes for time

OPEN (BUFFERED='YES')

Optimizes for time

Optimizes for time

OPEN (BUFFERED='NO')

Optimizes for space

Optimizes for time

If an input record's length is less than the specified block size, then by default, the runtime system always optimizes for time rather than for space. The input is buffered.

If an input record’s length is greater than the specified block size then the following occurs:

Optimizing for time:

Traditionally, optimizing for time comes at the expense of using more memory.

When the runtime system optimizes for time, it buffers input. It reads as much data as possible during one disk access into the runtime's internal buffer, extending it if necessary to hold the file's largest record. Fields within the record are then moved to the user space in response to READs from the file. Typically, minimizing disk accesses is faster.

However, there are circumstances when optimizing for space can actually be faster than optimizing for time.

For example, consider you are reading records whose length exceeds the block size and the data is being read into a contiguous array. Reading this huge array directly into a user's space is going to be faster than reading it first into the runtime system's internal buffer, then moving the data to the user's space. In this case, it is better to optimize for space; that is, you should not buffer the input record.

On the other hand, if the READ is being done into non-contiguous elements of an array, the traditional method of optimizing for time becomes a huge win. Data being read into non-contiguous array elements must be moved, or read, into the user's space one element at a time. In this case, you always want to optimize for time; that is, you should buffer the input data.

If you are reading large, variable length, unformatted records, you should try both buffered and unbuffered I/O to determine which delivers the better performance.

Optimizing for space:

Traditionally, optimizing for space comes at the expense of time.

When the runtime system optimizes for space, it wants to avoid creating a huge internal buffer in order to hold a "very large" record. The size of a "very large" record is clearly subjective, but the rule of thumb here is whether or not a record's size is greater than the specified block size.

If this is the case, the runtime system will read one field at a time from the record, directly into the user program's variable. The optimal record for this optimization is one whose record length exceeds the default block size of 128 KB (or a user-specified block size) and contains "very large" fields.

Note that because fields are read one at a time from disk to the user space, very large records that contain very small fields may see a serious performance issue. In these cases, it may be better to buffer the input. If you are reading large, variable length, unformatted records, you should try both buffered and unbuffered I/O to determine which delivers the better performance.

Examples

The following example shows an unformatted, sequential READ statement:

  READ (UNIT=6, IOSTAT=IO_STATUS) A, B, C

関連情報


このヘルプトピックについてのフィードバックを送信