HP OpenVMS Systems Documentation
HP Fortran for OpenVMS
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, 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:
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.
|File Type, Access, and I/O Form||Available Statements|
|External file, sequential access|
READ, WRITE, PRINT, ACCEPT, TYPE
1, and REWRITE
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|
READ, WRITE, and REWRITE
READ, WRITE, and REWRITE 1
|External file, keyed access|
READ, WRITE, and REWRITE
READ, WRITE, and REWRITE 1
|Internal file 2|
This section discusses file organization, internal and scratch files,
record type, record length, and other file characteristics.
6.5.1 File Organizations
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.
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).
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.
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.
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:
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.
Prior to each READ and WRITE statement, an internal file is always positioned at the beginning of the first record.
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.
Records are stored in one of the following record types:
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.
184.108.40.206 Portability Considerations of Record Types
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
220.127.116.11 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.)
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.
18.104.22.168 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.|
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'.
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.
22.214.171.124 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:
The layout of Stream_CR and Stream_LF records appears in Figure 6-2.
Figure 6-2 Stream_CR and Stream_LF Records
OPEN (UNIT=7,STATUS='OLD') READ (7,100)
READ (7,100) . . . TYPE 100
OPEN (UNIT=7, FILE='LOGNAM', STATUS='OLD')
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.