Kednos PL/I for OpenVMS Systems
User Manual


Previous Contents Index

6.3 Record Formats

OpenVMS Record Management Services (RMS) allows the following types of record formats:

Fixed-length records and variable-length records are allowed for all file organizations. Variable with fixed-length control records are allowed in sequential and relative files only.

You need specify the format only when you create a file. Thereafter, each time you open the file PL/I determines the format of the records in the file.

6.3.1 Fixed-Length Records

In a file containing fixed-length records, all records have the same length. Thus, when you create a file with fixed-length records, you must specify the length of each record in the file; this size cannot be changed thereafter.

To create a file with fixed-length records in a PL/I program, use the FIXED_LENGTH_RECORDS option of the ENVIRONMENT attribute. The MAXIMUM_RECORD_SIZE option specifies the size of each record. For example:


DECLARE FIXED_FILE FILE RECORD KEYED OUTPUT 
        ENVIRONMENT (FIXED_LENGTH_RECORDS, 
                     MAXIMUM_RECORD_SIZE(80)); 
When the file FIXED_FILE is opened, its record format is established as having fixed-length 80-character records.

When a file that has fixed-length records is processed by READ and WRITE statements, the file system checks the length of the variable specified in the INTO or FROM option to see if it is the same as the length of the records in the file. If not, the ERROR condition is signaled.

When you process a file with fixed-length records, you can specify the SCALARVARYING option of the ENVIRONMENT attribute (see Chapter 7) to process records in the standard PL/I manner.

6.3.2 Variable-Length Records

In a file consisting of variable-length records, each record can have a different size. RMS places a count field at the beginning of each record to indicate its size; however, this count field is not considered a part of the data record, nor is the length of the count field included in the size of the record.

Variable length is the default record format for PL/I files. You can specify the MAXIMUM_RECORD_SIZE option to specify the maximum length that any record can have. For example:


DECLARE VAR_FILE FILE RECORD OUTPUT 
        ENVIRONMENT (MAXIMUM_RECORD_SIZE(80)); 
This declaration indicates that the file VAR_FILE has variable-length records, each with a maximum length of 80 characters.

When a file that has variable-length records is processed by READ statements, the file system checks the length of the variable specified in the INTO option to see if it is large enough to hold the record being read. If not, the ERROR condition is signaled.

6.3.3 Variable-Length Records with a Fixed-Length Control Area

Variable-length records with a fixed-length control area are similar to variable-length records. However, they also contain a fixed-length control field. The control field size is the same for every record in the file.

The fixed control area in a record can contain data that is not related to the other data in the file. For example, a line-oriented editing program could use the fixed control area for sequence numbers.

To create a file of variable-length records with a fixed-length control area, specify the FIXED_CONTROL_SIZE option of the ENVIRONMENT attribute. The length of the control area you specify is a permanent attribute of the file; it cannot be changed later.

When you specify the maximum record length for a file containing variable-length with fixed-length control records, the length you specify does not include the length of the fixed control area. For example:


DECLARE VFC_FILE FILE RECORD 
        ENVIRONMENT ( 
                    MAXIMUM_RECORD_SIZE(250), 
                    FIXED_CONTROL_SIZE(2)); 
When the file VFC_FILE is opened for writing, the size of the fixed-length control area is set at 2 bytes; the maximum size of the data portion of any record is set at 250 bytes.

I/O operations on the file can process the fixed control area. The READ statement returns the contents of the fixed control area to a variable specified in the FIXED_CONTROL_TO option. The REWRITE and WRITE statements modify the fixed control area using the variable specified in the FIXED_CONTROL_FROM option, if any.

If this file is printed by the OpenVMS system, the contents of the fixed control area are printed to the left of each record.

6.4 Carriage Control

PL/I provides a default carriage control for files that will be printed. This format, called carriage return format, can be specified in the ENVIRONMENT option list (see Chapter 7) with the CARRIAGE_RETURN_FORMAT option; this option is never required.

When a file has carriage return format, the file can be output to a printer or terminal on a record-by-record basis. On output, each record is automatically preceded by a line feed (<LF>) character and followed by a carriage return (<CR>) character; these characters are not stored in the record. Thus, each record in the file occupies one line of output. This type of carriage control is valid for any file or record organization.

An alternative form of carriage control is the PRINTER_FORMAT option of the ENVIRONMENT attribute, which provides more explicit control of the output format and printing. Using printer format, you can specify such things as overprinting, skipping multiple lines, and so on. In a PL/I program, you will almost never need to use printer format; the PUT statement provides the same functions when it outputs data to a file with the PRINT attribute.

6.5 Sequential Files

This section shows examples of some typical sequential file I/O operations on sequential disk files and on sequential devices, including magnetic tapes.

6.5.1 Creating a Sequential File

Whenever a PL/I program opens a file with the SEQUENTIAL OUTPUT attributes, PL/I normally creates a new sequential file. By default, records are 510-byte, variable-length records. Each WRITE statement adds a new record to the file.

Appending Records to an Existing File

You can open a file with the APPEND option of the ENVIRONMENT attribute to add new records to the end of an existing sequential file. This overrides the default action of PL/I, which is to create a new version of an existing file when the existing file is opened for output. For example:


OPEN 
FILE(BIRD_FILE) OUTPUT SEQUENTIAL 
          TITLE('BIRDS.DAT') ENV(APPEND); 
WRITE FILE(BIRD_FILE) FROM (NEWDATA); 
This OPEN statement opens the file BIRD_FILE and positions it at its current end-of-file. The WRITE statement adds a new record at the end of the file.

Superseding an Existing File

The ENVIRONMENT option SUPERSEDE lets you create a new version of a file each time you write it, simultaneously deleting an existing version. By default, each time a specific file is written, PL/I gives it a new version number and does not replace the existing version. For example:


OPEN FILE(CONTROL) OUTPUT RECORD TITLE('CONTROL.DAT;1') 
       ENVIRONMENT(SUPERSEDE); 

This OPEN statement opens the file CONTROL.DAT;1. If this file already exists, it is deleted.

6.5.2 Using Magnetic Tape Files

Before you execute a PL/I program that reads or writes a sequential file on a magnetic tape volume, you must use the following sequence of DCL commands:

  1. Use the ALLOCATE command to allocate a device on which to mount the tape volume. For example:


    $ ALLOCATE MT:
      _MTA0:  ALLOCATED 
    
    The ALLOCATE command responds with the name of the physical device. You can now place the physical tape reel on the device.

  2. If the tape is a new tape that you are going to write or overwrite, use the INITIALIZE command to format the tape and write a label on it. For example:


    $ INITIALIZE MTA0:  MYTAPE
    

    This command writes the label MYTAPE on the tape volume mounted on MTA0: (the system printer device).

  3. Use the MOUNT command to ready the volume for use and, at your option, to define a logical name for the device and file. For example:


    $ MOUNT MTA0: MYTAPE TAPEFILE
    

After this sequence of commands, a PL/I program that writes records using the logical name TAPEFILE will be writing to the MTA0: tape volume. For example:


DECLARE OUTFILE FILE RECORD OUTPUT; 
OPEN FILE(OUTFILE) TITLE('TAPEFILE:TAPE1.FIL'); 

When this OPEN statement is executed, the logical name TAPEFILE is translated to its equivalence MTA0:, and the file MTA0:TAPE1.FIL;0 is created. Magnetic tape files always have a version number of 0.

Format of Magnetic Tapes

RMS supports the magnetic tape structure defined by ANSI X3.27-1977, the Magnetic Tape Labels and File Structure for Information Interchange. The tapes are encoded in ASCII format and can be processed on 9-track tape drives only.

The INITIALIZE command writes a label on the tape in the required format. A tape created on an OpenVMS system can be read on another system that supports the same tape label format.

Tape Positioning

When an existing magnetic tape file is opened, it is by default rewound, if necessary, and positioned at its beginning. This positioning can be overridden in the following ways:

By default, when a file is closed, the tape remains positioned after the last record that was read or written. The ENVIRONMENT option REWIND_ON_CLOSE can override this action and position the tape at its beginning.

While the file is open, the program can call the REWIND built-in subroutine to rewind the tape to its beginning.

For example:


DECLARE TAPEFILE FILE; 
 
OPEN FILE (TAPEFILE) OUTPUT RECORD ENVIRONMENT(APPEND); 
WRITE FILE (TAPEFILE) FROM (NEWREC); 
   .
   .
   .
CLOSE FILE(TAPEFILE) ENVIRONMENT (REWIND_ON_CLOSE); 
OPEN FILE(TAPEFILE) INPUT RECORD; 
In this example, the file TAPEFILE is opened for output with the APPEND option. WRITE statements add new records at the end of the tape file. Then, the CLOSE statement specifies that the tape is to be rewound, and the next OPEN statement opens the file for input. The first READ statement reads the first record in the file.

Blocking a Magnetic Tape File

On a magnetic tape, a block is a unit consisting of an integral number of records. Because of the control information needed to separate records on a tape, operations on a tape can be improved by blocking.

To create a blocked tape file, you must open it with the ENVIRONMENT option BLOCK_SIZE. This option specifies the size of the blocks. RMS automatically performs the blocking necessary. For example:


OPEN FILE(TAPEFILE) ENVIRONMENT( 
                     BLOCK_SIZE (2048), 
                     MAXIMUM_RECORD_SIZE (512), 
                     FIXED_LENGTH_RECORDS); 
WRITE FILE(TAPEFILE) FROM (BIG_RECORD); 
Following this opening, each WRITE statement writes a single record; the file system buffers the records until it accumulates four records and then transfers them, blocked, to the tape volume.

The BLOCK_SIZE option, if specified, is ignored when the output file is not a magnetic tape device. Thus, if you create and test a program that writes to a magnetic tape, you can test the program's output on a disk device; PL/I ignores the block size.

When a blocked magnetic tape file is read, RMS determines the block size from the tape itself, and deblocks the file as individual records are read.

Performing Block Input/Output

If a tape file is opened with the ENVIRONMENT option BLOCK_IO, the file can be read or written in terms of blocks. The size of a block is determined by the value of the BLOCK_SIZE option. Each I/O operation transfers the specified number of bytes. For example:


OPEN FILE (TAPEFILE) ENV (BLOCK_IO,BLOCK_SIZE(2048)); 
READ FILE (TAPEFILE) INTO (READBUF); 
These statements open the file TAPEFILE and read a 2048-byte block of data into the program variable READBUF. When a file is opened with the BLOCK_IO option, RMS does not block or deblock records. Your program must perform all necessary blocking and deblocking.

When a file is opened for block I/O, the program can advance the tape or move it backward a specified number of blocks by calling the SPACEBLOCK built-in subroutine. For example:


CALL SPACEBLOCK(TAPEFILE,3); 

This call advances the file TAPEFILE forward three blocks. The SPACEBLOCK built-in subroutine is described in Chapter 9.

Multivolume Tape Files

The ANSI standard X3.27-1977 for magnetic tapes allows any of the following combinations of tape files:

When more than one tape volume is required to contain a file or files, the tapes constitute a volume set. The OpenVMS system processes volume sets as follows:

Normally, RMS requests new volumes automatically. However, a PL/I program can request that the next volume in a volume set be mounted, for either an input or an output operation, by calling the NEXT_VOLUME built-in subroutine. The NEXT_VOLUME subroutine is described in Chapter 9.

The physical process of volume switching, whether the switching is performed automatically by RMS or as a result of a call to the NEXT_VOLUME built-in subroutine, is transparent to the PL/I program. As a user, you may wish to function as an operator to receive the volume switching requests and to mount the volumes yourself. For a description of the procedure for handling volume switching, see the OpenVMS DCL Dictionary.

6.5.3 Allocated and Spooled Devices

The OpenVMS system spools low-speed I/O devices such as printers by accumulating data for the device in a file, and then queuing the file for processing when it is closed.

In a PL/I program, when you specify a device name such as LPA0: in a TITLE option, the specified device may be currently allocated for use by another user or be spooled. Depending on the status of the device, the following can occur:

You can allocate a device before running a program by issuing the DCL command ALLOCATE. Within a PL/I program, you can invoke the system service SYS$ALLOC to allocate a device. For information on commands for device allocation and control, see the OpenVMS DCL Dictionary. For information on allocating devices using the SYS$ALLOC system service, see the OpenVMS System Services Reference Manual.

6.6 Relative Files

This section describes the organization of a relative file, suggests considerations for creating and using relative files, and shows examples of some typical relative file I/O operations.

6.6.1 Relative File Organization

The relative file organization is suitable for files with data that can be arranged serially and be uniquely identified by an integer value, for example, a part number or an employee identification number. Within the file, records are written into cells that are numbered; there is a one-to-one correspondence between the cell number and the integer value associated with the data in the record. This number, called the relative record number, is the key by which records are written and accessed.

Figure 6-1 illustrates a relative file in which not all cells contain records. The first record written to the file was relative record number 1 (which may have been data for a part numbered 1 or an employee whose number is 1, for example). The second record written was relative record number 2. The third record written was relative record number 4; thus cell number 3 does not contain a record.

Figure 6-1 A Relative File


Although the cells in a relative file have the same length, the records need not be fixed-length records. However, when a record is smaller than the length of a cell, the unused space is wasted.

6.6.2 Creating a Relative File

In PL/I relative file organization is the default organization for files that are opened with the KEYED attribute. Thus, when a WRITE statement is directed to a file with the KEYED and OUTPUT attributes, PL/I creates a relative file.

When you initially create a relative file in a PL/I program, you should give consideration to using the following ENVIRONMENT options to maximize the efficiency of I/O operations on the file:

Considerations for specifying values for each of these follow. For more detailed information on file design, see the OpenVMS Record Management Services Reference Manual.

Maximum Record Number

The MAXIMUM_RECORD_NUMBER option specifies the largest relative record number that will be used in the file, and thus specifies the maximum number of cells that the file can have. If you do not specify a maximum record number, PL/I sets the maximum record number to zero. This permits the file to expand to any size.

For example, if a relative file will contain inventory data on 600 parts, and the part number is to be used as the file key, the MAXIMUM_RECORD_NUMBER option can be specified as follows:


DECLARE PARTS FILE ENVIRONMENT ( 
               MAXIMUM_RECORD_NUMBER (600)); 

You should realistically allow for future expansion of the file when you specify a maximum record number; the number is a permanent attribute of the file and cannot be changed. PL/I signals the KEY condition when a key value is too large.

Maximum Record Size

When you specify the length of the records in a file, RMS uses the value you specify in the MAXIMUM_RECORD_SIZE option to calculate a cell size. It uses the following formulas to calculate the size:

When you select a record size for a relative file, you should try to specify a size that is no greater than the largest record that will be written. Otherwise, any unused space in each cell will be wasted. If you do not specify a maximum record size for either fixed- or variable-length records, PL/I uses the default length of 480 bytes.

Bucket Size

A bucket is the storage unit for data in the file. Records are arranged in buckets, which consist of an integral number of physically contiguous 512-byte disk blocks. Within the bucket, records can cross block boundaries; however, records cannot cross bucket boundaries.

When RMS transfers data from a file, it transfers data a bucket at a time; thus, a large bucket size reduces the number of actual data transfers that are required. When you do not specify a bucket size, RMS uses the cell size rounded to a multiple of 512 bytes. When records are written to the file, RMS places as many records as will fit in each bucket. Excess space is wasted.

You can improve I/O performance by specifying a bucket size that is a multiple of the cell size, and by calculating whether space is being wasted. For example:


DECLARE EMP_FILE OUTPUT RECORD ENVIRONMENT ( 
               FIXED_LENGTH_RECORDS, 
               MAXIMUM_RECORD_SIZE (80) 
               BUCKET_SIZE (4) ); 

The file EMP_FILE will be created with 81-byte cells and buckets that have 2048 bytes (that is, four 512-byte blocks). Each bucket can contain twenty-five 81-byte cells; 23 bytes in each bucket are unused.

When you specify a maximum record size and a bucket size for a relative file, you should consult the description of the BUCKET_SIZE option in Chapter 7. That description contains formulas for calculating the bucket size within the limits required by RMS.

File Size

To avoid the processing overhead that occurs when a file is extended beyond an initial default allocation, you can specify the FILE_SIZE option when you create a relative file. If you specify this option, you can preallocate all the space that will ever be required for the cells in the file.

To determine the space requirements of a file, you can use the following formulas. To compute the size of the file in 512-byte blocks:
file_size = (511 + ( number_of_buckets * bytes_per_bucket ) ) / 512

file_size

Is the size of the file in blocks.

number_of_buckets

Is the number of buckets in the file.

bytes_per_bucket

Is the number of bytes in each bucket.

To compute the number of buckets:
number_of_buckets = number_of_records / number_of_cells_per_bucket

number_of_buckets

Is the number of buckets in the file.

number_of_records

Is the number of records in the file.

number_of_cells_per_bucket

Is the number of records that can fit into a bucket.

You can also specify the CONTIGUOUS or CONTIGUOUS_BEST_TRY options in conjunction with the FILE_SIZE option to attempt to allocate all of the space for the file in contiguous disk blocks.

Extension Size

If you plan to add data to the file, you should specify a reasonable default extension size to reduce the number of times the file is extended. The FDL attribute FILE EXTENSION sets the extension size. The value to be assigned depends on the size of the records in the file and on the number of records that will be added to the file. The EDIT/FDL Utility calculates and assigns the correct extension size. For more information on the EDIT/FDL Utility, see Section 6.7.2.


Previous Next Contents Index