# Record Types

An I/O record is a collection of data items, called fields, which are logically related and are processed as a unit. The record type refers to the convention for storing fields in records.

The record type of the data within a file is not maintained as an attribute of the file. The results of using a record type other than the one used to create the file are indeterminate.

A number of record types are available, as shown in the following table. The table also lists the record overhead. Record overhead refers to bytes associated with each record that are used internally by the file system and are not available when a record is read or written. Knowing the record overhead helps when estimating the storage requirements for an application. Although the overhead bytes exist on the storage media, do not include them when specifying the record length with the RECL specifier in an OPEN statement.

Record Type | Available File Organizations and Portability Considerations | Record Overhead
--- | --- | ---
Fixed-length | Relative or sequential file organizations. | None for sequential or for relative if the vms option is omitted or option novms is specified. One byte for relative if the vms option is specified.
Variable-length | Sequential file organization only. The variable-length record type is generally the most portable record type across multi-vendor platforms. | Eight bytes per record.
Segmented | Sequential file organization only and specifically for unformatted sequential access. The segmented record type is unique to Intel Fortran. It should not be used for portability with programs written in languages other than Fortran or for places where Intel Fortran is not used. However, because the segmented record type is unique to Intel Fortran products, formatted data in segmented files can be ported across Intel Fortran platforms. | Four bytes per record. One additional padding byte (space) is added if the specified record size is an odd number.
Stream (uses no record terminator) | Sequential file organization only. | None required.
Stream_CR (uses CR as record terminator) | Sequential file organization only. | One byte per record.
Stream_LF (uses LF as record terminator) | Sequential file organization only. | One byte per record.
Stream_CRLF (uses CR and LF as record terminator) | Sequential file organization only. | Two bytes per record.

## Fixed-Length Records

When you specify fixed-length records, you are specifying that all records in the file contain the same number of bytes. When you open a file that is to contain fixed-length records, you must specify the record size using the RECL keyword. A sequentially organized opened file for direct access must contain fixed-length records, to allow the record position in the file to be computed correctly.

For relative files, the layout and overhead of fixed-length records depends upon whether the program accessing the file was compiled using the vms option:

- For relative files where the vms option is omitted (the default), each record has no control information.

- For relative files where the vms option is specified, each record has one byte of control information at the beginning of the record.

The following figures show the record layout of fixed-length records. The first is for all sequential and relative files where the vms option is omitted. The second is for relative files where the vms option is specified.

## Variable-Length Records

Variable-length records can contain any number of bytes up to a specified maximum record length, and apply only to sequential files.

Variable-length records are prefixed and suffixed by 4 bytes of control information containing length fields. The trailing length field allows a BACKSPACE request to skip back over records efficiently. The 4-byte integer value stored in each length field indicates the number of data bytes (excluding overhead bytes) in that particular variable-length record.

The character count field of a variable-length record is available when you read the record by issuing a READ statement with a Q format descriptor. You can then use the count field information to determine how many bytes should be in an I/O list.

The following shows the record layout of variable-length records that are less than 2 gigabytes:

For a record length greater than 2,147,483,639 bytes, the record is divided into subrecords. The subrecord can be of any length from 1 to 2,147,483,639, inclusive.

The sign bit of the leading length field indicates whether the record is continued or not. The sign bit of the trailing length field indicates the presence of a preceding subrecord. The position of the sign bit is determined by the endian format of the file.

The following rules describe sign bit values:

- A subrecord that is continued has a leading length field with a sign bit value of 1.

- The last subrecord that makes up a record has a leading length field with a sign bit value of 0.

- A subrecord that has a preceding subrecord has a trailing length field with a sign bit value of 1.

- The first subrecord that makes up a record has a trailing length field with a sign bit value of 0.

- If the value of the sign bit is 1, the length of the record is stored in twos-complement notation.

The following shows the record layout of variable-length records that are greater than 2 gigabytes:

Files written with variable-length records by Intel Fortran programs usually cannot be accessed as text files. Instead, use the Stream_LF record format for text files with records of varying length.

## Segmented Records

A segmented record is a single logical record consisting of one or more variable-length, unformatted records in a sequentially organized disk file. Unformatted data written to sequentially organized files using sequential access is stored as segmented records by default.

Segmented records are useful when you want to write exceptionally long records but cannot, or you do not want to define one long variable-length record. For example, you might not want to define one long variable-length record because virtual memory limitations can prevent program execution. By using smaller, segmented records, you reduce the chance of problems caused by virtual memory limitations on systems on which the program may execute.

For disk files, the segmented record is a single logical record that consists of one or more segments. Each segment is a physical record. A segmented (logical) record can exceed the absolute maximum record length (2.14 billion bytes), but each segment (physical record) individually cannot exceed the maximum record length.

To access an unformatted sequential file that contains segmented records, specify FORM='UNFORMATTED' and RECORDTYPE='SEGMENTED' when you open the file.

The following shows that the layout of segmented records consists of 4 bytes of control information followed by the user data:

The control information consists of a 2-byte integer record length count (includes the 2 bytes used by the segment identifier), followed by a 2-byte integer segment identifier that identifies this segment as one of the following:

Identifier Value | Segment Identified
--- | ---
0 | One of the segments between the first and last segments
1 | First segment
2 | Last segment
3 | Only segment

If the specified record length is an odd number, the user data will be padded with a single blank (one byte), but this extra byte is not added to the 2-byte integer record size count.

Avoid the segmented record type when the application requires that the same file be used for programs written in languages other than Intel Fortran and for non-Intel platforms.

## Stream File Data

A stream file is not grouped into records and contains no control information. Stream files are used with CARRIAGECONTROL='NONE'. They contain character or binary data that is read or written only to the extent of the variables specified on the input or output statement.

The following shows the layout of a stream file:

## Stream_CR, Stream_LF and Stream_CRLF Records

Stream_CR, Stream_LF, and Stream_CRLF records are variable-length records whose length is indicated by explicit record terminators embedded in the data, not by a count. These terminators are automatically added when you write records to a stream-type file and are removed when you read records.

Each variety uses either a different 1-byte or 2-byte record terminator:

- Stream_CR files must not contain embedded carriage-return characters because Stream_CR files use only a carriage-return as the terminator.

- Stream_LF files must not contain embedded line-feed (new line) characters because Stream_LF files use only a line-feed (new line) as the terminator. Stream_LF is the usual operating system text file record type on Linux* and macOS systems.

- Stream_CRLF files must not contain embedded carriage returns or line-feed (new line) characters because Stream_CRLF files use a carriage return/line-feed (new line) pair as the terminator. Stream_CRLF is the usual operating system text file record type on Windows* systems.

## Guidelines for Choosing a Record Type

Before you choose a record type, consider whether your application will use formatted or unformatted data. If you are using formatted data, you can choose any record type except segmented. If you are using unformatted data, avoid the Stream, Stream_CR, Stream_LF and Stream_CRLF record types.

The segmented record type can only be used for unformatted sequential access with sequential files. You should not use segmented records for files that are read by programs written in languages other than Intel Fortran.

The Stream, Stream_CR, Stream_LF, Stream_CRLF and segmented record types can be used only with sequential files.

The default record type (RECORDTYPE) depends on the values for the ACCESS and FORM specifiers for the OPEN statement. (The RECORDTYPE= specifier is ignored for stream access.)

The record type of the file is not maintained as an attribute of the file. The results of using a record type other than the one used to create the file are indeterminate.

An I/O record is a collection of fields (data items) that are logically related and are usually processed as a unit.

Unless you specify nonadvancing I/O (ADVANCE specifier), each Intel Fortran I/O statement transfers at least one record.

## Specifying the Line Terminator for Formatted Files

Use the FOR_FMT_TERMINATOR environment variable to specify the line terminator value used for Fortran formatted files with no explicit RECORDTYPE= specifier.

The FOR_FMT_TERMINATOR environment variable is processed once at the beginning of program execution. Whatever it specifies for specific units continues for the rest of the execution.

You can specify the numbers of the units to have a specific record terminator. The READ/WRITE statements that use these unit numbers will now use the specified record terminators. Other READ/WRITE statements will work in the usual way.

A RECORDTYPE=specifier on an OPEN statement overrides the value set by FOR_FMT_TERMINATOR. The FOR_FMT_TERMINATOR value is ignored for ACCESS='STREAM' files.

## General Syntax for FOR_FMT_TERMINATOR

The syntax for this environment variable is as follows:

    FOR_FMT_TERMINATOR=MODE[:ULIST][;MODE[:ULIST]]

where:

    MODE=CR | LF | CRLF
    ULIST = U | ULIST,U
    U = decimal | decimal - decimal

- MODE specifies the record terminator to be used. The keyword CR means to terminate records with a carriage return. The keyword LF means to terminate records with a line feed; LF is the default on Linux* and macOS systems. The keyword CRLF means to terminate records with a carriage return/line feed pair; CRLF is the default on Windows systems.

- Each list member "U" is a simple unit number or a number of units as a range. The number of list members is limited to 64.

- "decimal" is a non-negative decimal number less than 232.

No spaces are allowed inside the FOR_FMT_TERMINATOR value.

On Linux* systems, the following shows the command line for the variable setting in a bash-style shell:

    Sh: export FOR_FMT_TERMINATOR=MODE:ULIST

### Note

The environment variable value should be enclosed in quotes if the semicolon is present.

Example:

The following specifies that all input/output operations on unit numbers 10, 11, and 12 have records terminated with a carriage return/line feed pair:

    FOR_FMT_TERMINATOR=CRLF:10-12

Parent topic: Fortran I/O