HP OpenVMS Systems Documentation

Content starts here

HP Fortran for OpenVMS
User Manual


Previous Contents Index

6.4 Forms of I/O Statements

Each type of record I/O statement can be coded in a variety of forms. The form you select depends on the nature of your data and how you want it treated. When opening a file, specify the form using the FORM specifier. The following are the forms of I/O statements:

  • Formatted I/O statements contain explicit format specifiers that are used to control the translation of data from internal (binary) form within a program to external (readable character) form in the records, or vice versa.
  • List-directed and namelist I/O statements are similar to formatted statements in function. However, they use different mechanisms to control the translation of data: formatted I/O statements use explicit format specifiers, and list-directed and namelist I/O statements use data types.
  • Unformatted I/O statements do not contain format specifiers and therefore do not translate the data being transferred (important when writing data that will be read later).

Formatted, list-directed, and namelist I/O forms require translation of data from internal (binary) form within a program to external (readable character) form in the records. Consider using unformatted I/O for the following reasons:

  • Unformatted data avoids the translation process, so I/O tends to be faster.
  • Unformatted data avoids the loss of precision in floating-point numbers when the output data will subsequently be used as input data.
  • Unformatted data conserves file storage space (stored in binary form).

To write data to a file using formatted, list-directed, or namelist I/O statements, specify FORM= ' FORMATTED ' when opening the file. To write data to a file using unformatted I/O statements, specify FORM= ' UNFORMATTED ' when opening the file.

Data written using formatted, list-directed, or namelist I/O statements is referred to as formatted data; data written using unformatted I/O statements is referred to as unformatted data.

When reading data from a file, you should use the same I/O statement form that was used to write the data to the file. For instance, if data was written to a file with a formatted I/O statement, you should read data from that file with a formatted I/O statement.

Although I/O statement form is usually the same for reading and writing data in a file, a program can read a file containing unformatted data (using unformatted input) and write it to a separate file containing formatted data (using formatted output). Similarly, a program can read a file containing formatted data and write it to a different file containing unformatted data.

As described in Section 6.9.2, you can access records in any sequential, relative, or indexed file using sequential access. For relative files and fixed-length sequential files, you can also access records using direct access. For indexed files, you can use keyed access.

Table 6-2 shows the main record I/O statements, by category, that can be used in HP Fortran programs.

Table 6-2 Available I/O Statements and Record I/O Forms
File Type, Access, and I/O Form Available Statements
External file, sequential access  
Formatted
List-Directed
Namelist
Unformatted
READ, WRITE, PRINT, ACCEPT, TYPE 1, and REWRITE 1
READ, WRITE, PRINT, ACCEPT 1, TYPE 1, and REWRITE 1
READ, WRITE, PRINT, ACCEPT 1, TYPE 1, and REWRITE 1
READ, WRITE, and REWRITE 1
External file, direct access  
Formatted
Unformatted
READ, WRITE, and REWRITE 1
READ, WRITE, and REWRITE 1
External file, keyed access  
Formatted
Unformatted
READ, WRITE, and REWRITE 1
READ, WRITE, and REWRITE 1
Internal file 2  
Formatted
List-Directed
Unformatted
READ, WRITE
READ, WRITE
None

1This statement is an HP extension to the Fortran 90 and Fortran 95 standards.
2An internal file is a way to reference character data in a buffer using sequential access (see Section 6.5.2).

6.5 Types of Files and File Characteristics

This section discusses file organization, internal and scratch files, record type, record length, and other file characteristics.

6.5.1 File Organizations

File organization refers to the way records are physically arranged on a storage device.

The default file organization is always ORGANIZATION= ' SEQUENTIAL ' for an OPEN statement.

HP Fortran supports three kinds of file organizations: sequential, relative, and indexed sequential. The organization of a file is specified by means of the ORGANIZATION specifier in the OPEN statement.

You must store relative files on a disk device. You can store sequential files on magnetic tape or disk devices, and can use other peripheral devices, such as terminals and line printers, as sequential files.

File characteristics, including the file organization and record type, are stored by RMS in the disk file header and can be obtained by using the INQUIRE statement. You can also view the organization of a file using the DCL command DIRECTORY/FULL.

For more information on the INQUIRE statement, see Section 6.7 and the HP Fortran for OpenVMS Language Reference Manual.

Sequential Organization

A sequentially organized file consists of records arranged in the sequence in which they are written to the file (the first record written is the first record in the file, the second record written is the second record in the file, and so on). As a result, records can be added only at the end of the file.

Sequential files are usually read sequentially, starting with the first record in the file. Sequential files stored on disk with a fixed-length record type can also be accessed by relative record number (direct access).

Relative Organization

Within a relative file are numbered positions, called cells. These cells are of fixed equal length and are consecutively numbered from 1 to n, where 1 is the first cell, and n is the last available cell in the file. Each cell either contains a single record or is empty.

Records in a relative file are accessed according to cell number. A cell number is a record's relative record number (its location relative to the beginning of the file). By specifying relative record numbers, you can directly retrieve, add, or delete records regardless of their locations (direct access).

Relative files allow you to use direct access and detect when a record has been deleted.

When creating a relative file, specify the RECL value to determine the size of the fixed-length cells. Within the cells, you can store variable-length records as long as their size does not exceed the cell size.

Indexed Files

An indexed file consists of two or more separate sections: one section contains the data records and the other sections contain indexes. When an indexed file is created, each index is associated with a specification defining a field within each record, called a key field or simply key. A record in an indexed file must contain at least one key, called the primary key, which determines the location of the records within the body of the file.

The keys of all records are collected to form one or more structured indexes, through which records are always accessed. The structure of the indexes allows a program to access records in an indexed file either randomly (keyed access) or sequentially (sequential access). With keyed access, you specify a particular key value. With sequential access, you retrieve records with increasing or decreasing key values. You can mix keyed access and sequential access.

Indexed files are supported only on disk devices. When creating an indexed file, specify the RECL value.

For more information on indexed files, see Chapter 12.

6.5.2 Internal Files and Scratch Files

HP Fortran also supports two other types of files that are not file organizations---namely, internal files and scratch files.

Internal Files

You can use an internal file to reference character data in a buffer when using sequential access. The transfer occurs between internal storage and internal storage (unlike external files), such as between character variables and a character array.

An internal file consists of any of the following:

  • Character variable
  • Character-array element
  • Character array
  • Character substring
  • Character array section without a vector subscript

Instead of specifying a unit number for the READ or WRITE statement, use an internal file specifier in the form of a character scalar memory reference or a character-array name reference.

An internal file is a designated internal storage space (variable buffer) of characters that is treated as a sequential file of fixed-length records. To perform internal I/O, use formatted and list-directed sequential READ and WRITE statements. You cannot use such file-related statements such as OPEN and INQUIRE on an internal file (no unit number is used).

If an internal file is made up of a single character variable, array element, or substring, that file comprises a single record whose length is the same as the length of the variable, array element, or substring. If an internal file is made up of a character array, that file comprises a sequence of records, with each record consisting of a single array element. The sequence of records in an internal file is determined by the order of subscript progression.

A record in an internal file can be read only if the character variable, array element, or substring comprising the record has been defined (a value has been assigned to the record).

Prior to each READ and WRITE statement, an internal file is always positioned at the beginning of the first record.

Scratch Files

Scratch files are created by specifying STATUS= ' SCRATCH ' on an OPEN statement. By default, the files are created on the user's default disk (SYS$DISK) and are not placed in a directory or given a name that is externally visible (accessible using the DCL command DIRECTORY).

You can create scratch files on a disk other than the default disk by using the FILE specifier in an OPEN statement.

6.5.3 I/O Record Types

Record type refers to whether records in a file are all the same length, are of varying length, or use other conventions to define where one record ends and another begins.

You can use fixed-length and variable-length record types with sequential, relative, or indexed files. You can use any of the record types with sequential files.

Records are stored in one of the following record types:

  • Fixed-length
  • Variable-length
  • Segmented
  • Stream

  • Stream_CR
  • Stream_LF

You can use fixed-length and variable-length record types with sequential, relative, or indexed files.

Before you choose a record type, consider whether your application will use formatted or unformatted data. If you will be using formatted data, you can use any record type except segmented. When using unformatted data, you should avoid using the stream, stream_CR, and stream_LF record types.

The segmented record type is unique to HP Fortran products; it is not used by other OpenVMS-supported languages. It 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 Fortran.

The stream, stream_CR, stream_LF, and segmented record types can only be used with sequential files.

6.5.3.1 Portability Considerations of Record Types

Consider the following portability needs when choosing a record type:

  • Data files from HP Fortran and Compaq Fortran 77 on OpenVMS systems are interchangeable.
  • You can use any any record type except segmented with other non-Fortran OpenVMS languages.

HP Fortran indexed files are portable only to other OpenVMS systems. However, a conversion program can read the records from an indexed file and write them to another file, such as a sequential (or relative) file.

6.5.3.2 Fixed-Length Records

When you create a file that uses the fixed-length record type, you must specify the record size. When you specify fixed-length records, all records in the file must contain the same number of bytes. (The HP Fortran for OpenVMS Language Reference Manual discusses fixed-length records.)

A sequential file opened for direct access must contain fixed-length records, to allow the record position in the file to be computed correctly.

You can obtain the record length (RECL) before opening the file with unformatted data by using a form of the INQUIRE statement (see Section 6.7.3).

6.5.3.3 Variable-Length Records

Variable-length records can contain any number of bytes, up to a specified maximum. These records are prefixed by a count field, indicating the number of bytes in the record. The count field comprises two bytes on a disk device and four bytes on magnetic tape. The value stored in the count field indicates the number of data bytes in the record.

Variable-length records in relative files are actually stored in fixed-length cells, the size of which must be specified by means of the RECL specifier in an OPEN statement (see the HP Fortran for OpenVMS Language Reference Manual for details). This RECL value specifies the largest record that can be stored in the file.

The count field of a formatted 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.

6.5.3.4 Segmented Records

A segmented record is a single logical record consisting of one or more variable-length, unformatted records in a sequential file. Each variable-length record constitutes a segment. The length of a segmented record is arbitrary.

Segmented records are useful when you want to write exceptionally long records but cannot or do not wish to define one long variable-length record. When writing unformatted data to a sequential file using sequential access, the default record type is segmented.

As shown in Figure 6-1, the layout of segmented records consists of control information followed by the user data. On disk, the control information consists of four bytes for compatibility with other HP Fortran platforms. However, OpenVMS RMS removes the first two length bytes when the record is read, so each record has two control bytes (flags) in memory.

Figure 6-1 Segmented Records


The control information consists of a 2-byte integer record size count (includes the two 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.

When you wish to access an unformatted sequential file that contains variable-length records, you must specify FORM='UNFORMATTED' when you open the file. If the unformatted data file was not created using an HP Fortran product, specify RECORDTYPE='VARIABLE'. If the unformatted data file was created using the segmented record type using an HP Fortran Fortran product, specify RECORDTYPE='SEGMENTED'.

Otherwise, the first two bytes of each record will be mistakenly interpreted as control information, and errors will probably result.

You can obtain the record length (RECL) before opening the file with unformatted data using a form of the INQUIRE statement (see Section 6.7.3).

6.5.3.5 Stream Records

A stream record is a variable-length record whose length is indicated by explicit record terminators embedded in the data, not by a count.

Stream files use the 2-character sequence consisting of a carriage-return and a line-feed as the record terminator. These terminators are automatically added when you write records to a stream file and removed when you read records.

Stream records resemble the Stream_CR or Stream_LF records shown in Figure 6-2, but use a 2-byte record terminator (carriage-return and line-feed) instead of a 1-byte record terminator.

6.5.3.6 Stream_CR and Stream_LF Records

A Stream_CR or Stream_LF record is a variable-length record 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 a different 1-byte record terminator:

  • Stream_CR files use only a carriage-return as the terminator, so Stream_CR files must not contain embedded carriage-return characters.
  • Stream_LF files use only a line-feed (new line) as the terminator, so Stream_LF files must not contain embedded line-feed (new line) characters.

The layout of Stream_CR and Stream_LF records appears in Figure 6-2.

Figure 6-2 Stream_CR and Stream_LF Records


6.5.4 Other File Characteristics

Other file characteristics include:

  • Carriage control attributes of each record (CARRIAGECONTROL specifier)
  • Whether formatted or unformatted data is contained in the records (FORM specifier)
  • The record length (RECL specifier)
  • Whether records can span block boundaries (NOSPANBLOCK specifier)
  • For an indexed file being created, the key number, its location, and its data type (KEY specifier)

The units used for specifying record length depend on the form of the data:

  • For formatted files (FORM= ' FORMATTED ' ), specify the record length in bytes.
  • For unformatted files (FORM= ' UNFORMATTED ' ), specify the record length in 4-byte units, unless you specify the /ASSUME=BYTERECL qualifier to request 1-byte units (see Section 2.3.7).

For More Information:

  • On statement syntax and specifier values (including defaults), see the HP Fortran for OpenVMS Language Reference Manual.
  • On file characteristics, see Section 6.6.3 and the OPEN statement in the HP Fortran for OpenVMS Language Reference Manual.
  • On I/O performance considerations, see Section 5.5.

6.6 Opening Files and the OPEN Statement

You can choose to open files by:

  • Using default values, such as a preconnected unit. In the following example, the PRINT statement is associated with a preconnected unit (SYS$OUTPUT) by default:


    PRINT *,100
    

    Implicitly opening a file by omitting an OPEN statement prevents you from specifying the file connection characteristics and other information provided by the OPEN statement. You might use implicit opening of a file for terminal I/O.
    The following READ statement associates the logical unit 7 with the file FOR007.DAT (because the FILE specifier was omitted) by default:


    
    OPEN (UNIT=7,STATUS='OLD')
    READ (7,100)
    
    
  • Using default logical names, which allows you to specify which file or files are used at run time. If the following example uses an implicit OPEN, the READ statement causes the logical name FOR007 to be associated with the file FOR007.DAT by default. The TYPE statement causes the logical unit FOR$TYPE to be associated with SYS$OUTPUT by default.


      READ (7,100)
        .
        .
        .
      TYPE 100
    
  • Using logical names without an OPEN statement. You can also use DCL commands to set the appropriate logical names to a value that indicates a directory (if needed) and a file name to associate a unit with an external file.
  • Specifying a logical name in an OPEN statement. This allows you to specify which file or files are used at run time, but the appropriate logical names must be defined before the program is run. For example:


      OPEN (UNIT=7, FILE='LOGNAM', STATUS='OLD')
    
  • Specifying a file specification in an OPEN statement. The file or files are specified at compile time, so the program may need to be recompiled to specify a different file (or the default device and directory changed if these are not specified by the program). For example:


      OPEN (UNIT=7, FILE='FILNAM.DAT', STATUS='OLD')
    

If you choose to specify a logical name with the FILE specifier in an OPEN statement, that logical name must be associated with a file specification and the character expression specified for the logical name must contain no punctuation marks.


Previous Next Contents Index