File I/O
This chapter describes file I/O of PL/I.
1. Overview
OpenFrame PI/O supports two types of file I/O processing. Data are differently processed in each type.
-
Record I/O
-
Data are inputted and outputted on storage without data conversion.
-
The READ, WRITE, DELETE, REWRITE, and LOCATE statements are valid. A single data is processed per statement.
-
-
Stream I/O
-
Data are converted to a character value. They are inputted and outputted as stream.
-
The GET and PUT statements are valid. One or more data are processed per statement.
-
File
A file variable that has the attribute File must be specified for using file I/O. A file variable is connected to external datasets and it specifies the attribute of the external dataset.
The attributes associated with a file are valid in the DECLARE or OPEN statements. However, the ENVIRONMENT attribute is only valid in the DECLARE statement. The following is the attributes associated with files.
Attribute | Description |
---|---|
RECORD, STREAM |
File I/O type.
|
INPUT, OUTPUT, UPDATE |
Direction of the data set.
Stream I/O cannot use the UPDATE attribute. |
SEQUENTIAL, DIRECT |
Access type of the data set.
Stream I/O can only use the SEQUENTIAL attribute. |
BUFFERED, UNBUFFERED |
Option to use a buffer when processing records.
The default value of the SEQUENTIAL file is BUFFERED, and the default value of the DIRECT file is UNBUFFERED. Stream I/O cannot use the UNBUFFERED attribute. |
ENVIRONMENT |
Various data set characteristics as shown below.
|
KEYED |
Only applies to RECORD files. This attribute can be used in indexed or relative data sets. This attribute specifies that records in the file can be accessed using the KEY, KEYTO, or KEYFROM options of I/O statements. |
Sets the file to be printed. This attribute is valid in STREAM OUTPUT files. The LINESIZE and PAGESIZE options can be specified in OPEN statement, and the PAGE and LINE options can be specified in PUT statement. In addition, data are separated by tabs, and character data values are not enclosed in quotation marks. |
SYSPRINT and SYSIN
SYSPRINT and SYSIN are the files provided by PL/I program. These files are created within the PL/I program and need not be declared or opened explicitly.
SYSPRINT is output file and SYSIN is input file. SYSIN has the STREAM and INPUT attributes by default, and SYSPRINT has STREAM, OUTPUT, and PRINT attributes by default.
2. Statement
This section describes the statements associated with files.
2.1. OPEN Statement
The OPEN statement opens a specified file.
open-options:
Component | Description |
---|---|
FILE |
File to open. |
FILE attribute |
Refer to File. |
TITLE |
DD name of an external dataset described in a JCL. |
LINESIZE |
Length of a line. (Default value: 120) If a stream length exceeds LINESIZE, the next line will be used from the first column. This option can be used only for STREAM OUTPUT files. |
PAGESIZE |
Number of lines in a page. (Default value: 60) If a line exceeds PAGESIZE, the ENDFILE condition will occur. A new page can start using a PAGE format item or the PAGE option in a PUT statement. |
A file can be opened explicitly by using an OPEN statement. An unopened file opens when using a READ, WRITE, REWRITE, DELETE, LOCATE, PUT, or GET statement.
A FILE attribute that was defined during a declaration can be redefined by defining the attribute when explicitly opening a file using an OPEN statement. The following example redefines the FILE attribute using an OPEN statement.
DECLARE TEST FILE RECORD OUTPUT; OPEN FILE(TEST) STREAM INPUT; CLOSE FILE(TEST); OPEN FILE(TEST);
In the first OPEN statement, TEST has the STREAM and INPUT attributes. Once a file is closed, the FILE attribute is lost and not applied when the file is reopened. Therefore, in the second OPEN statement, TEST has the RECORD and OUTPUT attributes specified in the DECLARE statement.
If the FILE attribute defined during declaration is different from the attribute defined during opening, an error will occur. |
3. Record I/O
Record I/O processes the records in the storage without data conversion.
Record I/O can be used in consecutive, indexed, or relative data set. Records are inputted or outputted sequentially or they can be inputted or outputted directly using a key. The value of a record can be stored or written in a variable or accessed using a pointer.
3.1. READ Statement
The READ statement reads records from a dataset. The read record can be saved to a variable or pointed by a pointer.
Component | Description |
---|---|
FILE |
File to read. The file must have the INPUT or UPDATE attributes. |
IGNORE |
Sets a value for the number of records to be ignored. If an evaluated expression value is n and the IGNORE option is used, the (n+1)th record will be read. |
INTO |
Saves a read record to a specified variable. If the variable is an array or a structure, it must be assigned to storage. |
SET |
Specified pointer that points to a read record. |
KEY |
Record that corresponds to a specified KEY to be read. To use the KEY option, the file must have the DIRECT or SEQUENTIAL KEYED attribute. |
KEYTO |
Reads a record’s key value when a record is read. To use the KEYTO option, a file must have the SEQUENTIAL KEYED attribute. |
3.2. WRITE Statement
The WRITE statement writes a record to a dataset.
Component | Description |
---|---|
FILE |
File to write. The file must have the OUTPUT or UPDATE attributes. |
FROM |
Variable to which a record is written. If the variable is an array or a structure, it must be assigned to storage. |
KEYFROM |
Key of a record to write. To use the KEYFROM option, a file must have the KEYED attribute. The value of KEYFROM is converted to a CHARACTER in an indexed dataset, or a FIXED DECIMAL in a relative dataset. |
KEYTO |
Key of the next record to write. To use the KEYTO option, a file must have the SEQUENTIAL KEYED attribute. |
3.3. DELETE Statement
The DELETE statement deletes a record from a file.
Component | Description |
---|---|
FILE |
File that includes a record to delete. The file must have the UPDATE attribute. |
KEY |
Record that corresponds with a specified KEY is removed. To use the KEY option, the file must have the DIRECT or SEQUENTIAL KEYED attributes. |
3.4. REWRITE Statement
The REWRITE statement updates a record in a dataset.
Component | Description |
---|---|
FILE |
File to update. The file must have the UPDATE attribute. |
FROM |
Variable to which a record is saved. If the variable is an array or a structure, it must be assigned to storage. |
KEY |
Record that corresponds to a specified KEY is updated. To use the KEY option, the file must have the DIRECT or SEQUENTIAL KEYED attributes. |
3.5. LOCATE Statement
The LOCATE statement specifies the location of an output buffer using a pointer to enable access to the buffer through a based variable.
Component | Description |
---|---|
FILE |
Target file with a OUTPUT SEQUENTIAL BUFFERED attribute. |
based variable |
Based variable that enables access to an output buffer. |
SET |
Pointer to which the address of an output buffer is saved. |
KEYFROM |
Key of a record to write. To use the KEYFROM option, a file must have the KEYED attribute. The value of KEYFROM is converted to a CHARACTER in an indexed dataset or a FIXED DECIMAL in a relative dataset. |
A record will be written when a buffer is flushed using a FLUSH statement, or when the next LOCATE statement is executed, not when a LOCATE statement is executed. Therefore, a record to be written to a dataset can be modified using a based variable even if a LOCATE statement is executed. |
4. Stream I/O
Stream I/O converts data into a character string value and it creates multiple data as stream. Stream is a storage where the data converted to a character string are stored sequentially. The specified length of stream data are read or written from or to the data set. Even if the stream is divided into multiple records, the records are internally processed as a single stream.
Stream I/O can be only used in consecutive data sets. It also allows only sequential processing. In stream I/O, data are created as a stream or read from a stream.
This section describes three methods of processing data as a stream, which use GET and PUT statements.
4.1. GET Statement
The GET statement reads records from a stream that can be fetched from a dataset or string.
When reading data from a dataset, the syntax of the GET statement is as follows:
Component | Description |
---|---|
FILE |
Target file. (Default value: SYSIN file) |
data-specification |
Refer to Data Specification. |
COPY |
Saves a copy of the fetched stream in the specified file. If no file is specified, the copy is saved in the SYSPRINT file. |
SKIP (expression) |
Sets an expression value and skips the amount of data set, then reads the data after the skipped data. (Default value: 1) |
When reading data from a string, the syntax of the GET statement is as follows:
Component | Description |
---|---|
STRING |
Target string. |
data-specification |
Refer to Data Specification. |
4.2. PUT Statement
The PUT statement creates a record of saves as a stream that can be saved to a dataset or string.
When saving data to a dataset, the syntax of the PUT statement is as follows:
Component | Description |
---|---|
FILE |
Target file. (Default value: SYSIN file) |
data-specification |
Refer to Data Specification. |
SKIP (expression) |
Sets a number of lines to skip. (Default value: 1) |
LINE (expression) |
Sets a value of lines to move. To use the LINE option, a file must have the PRINT attribute. |
PAGE |
Starts a new page. The default start line value is 1. To use the PAGE option, a file must have the PRINT attribute. |
When saving data to a string, the syntax of the PUT statement is as follows:
Component | Description |
---|---|
STRING |
Target string. |
data-specification |
Refer to Data Specification. |
4.3. Data Specification
The following shows the syntax of data specification of the GET and PUT statements.
data list:
format list:
Component | Description |
---|---|
LIST |
For more information, refer to List-directed I/O. |
DATA |
For more information, refer to Data-directed I/O. |
EDIT |
For more information, refer to Edit-directed I/O. |
data-list item |
|
data-list DO Type 3 |
Refer to the syntax of DO statement Type3. DO Type 3 can be enclosed in parentheses. Refer to the below example. |
format list |
For more information, refer to Format Item. |
The example of data-list DO Type 3 is as shown below.
PUT LIST(((A(I,J), B(I,J) DO I = 1 TO 3) DO J = 3 TO 4));
DO J = 3 TO 4 is the outermost repetitive specification, DO I = 1 TO 2 is the innermost specification, and A(I,J), B(I,J) in the innermost set is a do-group. Therefore, the above example is the same as the below example.
DO J = 3 TO 4; DO I = 1 TO 2; PUT LIST(A(I,J), B(I,J)); END; END;
4.3.1. List-directed I/O
On list-directed I/O, data are processed sequentially. Data are converted according to the type through the conversion rule. Each data is delimited by blank spaces when they are inputted and outputted.
-
List-directed input
-
When the data is a character value, it is saved after quotation marks are removed.
-
When the data is an arithmetic constant, its base, scale, mode, and precision are set using the attribute of the data-list item that will be actually saved.
-
The following is an example.
GET LIST(A,B,C,D);
Main feature of stream I/O is that multiple data can be processed using a single statement.
The above example is the same as the below example.
GET LIST(A); GET LIST(B); GET LIST(C); GET LIST(D);
When data exist in a stream as shown below, 100, 90, 80, and 70 are stored in A, B, C, and D respectively.
100 90 80 70
If the type of the stream data and that of the variable to be stored are different, a conversion occurs. When the conversion fails, the CONVERSION condition is raised.
-
-
List-directed output
-
Data-list items are converted to a character string and created as a stream.
-
If the data is a coded arithmetic constant, it is converted to a character string through the conversion rule when that data outputs.
-
If the data is a bit value, quotation marks are added at the beginning and end of the data and the character B is added when that data outputs.
-
If the data is a character value, the data outputs depending whether or not the PRINT attribute is applied to the file.
-
If the PRINT attribute does not exist in the file, quotation marks are added at the beginning and end of the data when that data outputs.
-
If the PRINT attribute exists in the file, quotation marks are not added at the beginning and end of the data when that data outputs.
-
-
The following is an example.
DCL A FIXED DEC INIT(15); DCL B CHAR(4) INIT('TEST'); DCL C BIT(8) INIT('11110000'); PUT LIST(A,B,C);
The stream created in the above example is as shown below.
15 TEST '11110000'B
SYSPRINT is basically specified when the FILE option is not set in the PUT statement. Since SYSPRINT has the PRINT attribute, quotation marks are not added to the character string.
List-directed output is valid for expressions as well as references.
-
The following is the example and result of multiple expressions.
PUT LIST('AB' || 'CD', 5 * 15, 1.5E+2);
ABCD 75 1.5E+0002
-
4.3.2. Data-directed I/O
On data-directed I/O, the stream data consists of a name and value. Each data-list item including name and value are separated by '='.
The syntax of the stream data created through data-directed I/O is as shown below.
-
Data-directed input
-
Unlike list-directed input, data are not saved to items in order. The name and item of the data must be the same when they are saved.
In addition, whereas data are read as many as the items specified in the GET statement on data-directed input, stream is read by the semicolon (;) unit on data-directed input.
-
The following is an example.
GET DATA(A,B,C,E);
If data exist in a stream as shown below, 10, 20, and 30 are stored in A, B, and C respectively.
B= 20 A= 10 C= 30 D= 40;
When the name of data is the same as that of the item, the values of data are saved excluding the name and '='. The order of data is not important before a semicolon appears in the stream. In this example, since the data list contains E that is not included in the stream, the value of E remains unchanged. Since the stream contains D that is included in the data list, D is ignored. When an array or structure variable appears in the data-list, data transmission does not occur.
-
-
Data-directed output
-
The names and values of a data list are converted to a character string when they are saved to a stream.
-
When an array or structure variable appears in a data list, a subscript or qualified name is included in the data name.
-
The following is an example of data-directed output that uses an array and structure variable.
DCL A(3) CHAR(2) INIT('12','34','56'); DCL 1 B, 2 C FIXED DEC INIT(3), 2 D, 3 E FIXED DEC INIT(5); PUT DATA(A, B);
The stream created in the above example is as shown below.
A(1)='12' A(2)='34' A(3)='56' B.C= 3 B.D.E= 5;
A semicolon appears in the stream when a single PUT statement ends. Therefore, transmission ends if a semicolon is enclosed when a single GET statement is executed on data-direct input.
-
4.3.3. Edit-directed I/O
On edit-directed I/O, data are processed by specifying a format. Data-list items are converted according to the specified format. Control format plays the role of blank space or line-break character. For more information about the format, refer to Format Item. The number of control-format items may not be equivalent to that of data-list items.
The following is an example.
PUT EDIT(A,B,C)(A(4),F(15,6));
In this example, the number of data-list items are 3, which are A, B, and C. But, the number of format items are 2, which are A(4) and F(15). When the end of the format is reached, the execution returns back to the beginning of the format.
PUT EDIT(A,B)(A(4),F(15,6),B(8));
If the number of format items is greater than that of data-list items, the remaining format items are ignored. Therefore, B(8) is not used in this example.
A format-item is an integration factor, which can integrate as many times as the format item is specified.
-
Edit-directed input
-
Unlike list-directed input and data-directed input, data are not separated by blank spaces on edit-directed input.
All characters that exist in the stream are included in the data. The user must manually separate the data using the format item.
-
The following is the example of an edit-directed input.
GET EDIT(A,B,C)(A(4),A,X(4),F(6,2));
The above example is processed as follows.
-
4 characters are saved from the stream to A.
-
The specified number of characters in B are read from the data and then saved to B.
-
The next 4 characters are ignored.
-
The next 6 characters are a fixed-point format and they are saved to C.
-
-
-
Edit-directed output
-
Unlike list-directed or data-directed input, data are not separated by blank spaces on data-directed input. The data are saved to the stream in the same way the formats are specified.
-
The following is the example of an edit-directed output.
PUT EDIT(A,B,'edit direct')(SKIP(1),A(2),X(4),F(15,4),COL(30),A(11));
The above example is processed as follows.
-
One line is skipped.
-
A is converted to 2 characters and then it is saved to the stream. If the length of A is greater than 2, the remaining data is truncated.
-
4 characters of blank spaces are saved to the stream.
-
B is a fixed-pint type. It is converted to 15 decimal digits and 4 digit precisions and then it is saved to the stream.
-
The 'edit direct' character string is saved with the length 11 in the column position 30.
-
-
FORMAT statement
For more information about format statements, refer to FORMAT Statement.
4.4. Format Item
Format items are divided into three types.
-
Control format item
-
The format associated with the data set layout.
-
COLUMN, LINE, PAGE, SKIP, and X formats
-
-
Data format item
-
The format for inputting and outputting data-list items.
-
A, B, E, F, and P formats
-
-
Remote format item
-
Format for setting a format list.
-
R format
-
4.4.1. A-format
A-format is a data format for representing a character value.
-
On input, if an A-format is specified with a length, the specified number of characters is read from the data stream. If an A-format item is specified without a length, the data is read from the data stream as much as specified in the data-list item.
-
On output, if an A-format is specified with a length, the specified number of characters is saved to the stream. If the length specified in an A-format is equal to or less than the length of the data-list item, the data-list item is truncated or padded. If an A-format is specified without a length, the data is read from the data stream as much as specified in the data-list item.
Component | Description |
---|---|
field-width |
Length of a character value. The value is converted to an integer and cannot be a negative value. If field-width is omitted, it defaults to the data length. |
4.4.2. B-format
B-format is a data format for representing a bit value.
-
On input, B format is not yet supported.
-
On output, data is converted to a bit value and then saved to the stream. For more information about the conversion rule, refer to Data Conversion.
Component | Description |
---|---|
field-width |
Length of a bit value. The value is converted to an integer and cannot be a negative value. If field-width is omitted, it defaults to the data length. |
4.4.3. COLUMN format
COLUMN format is a control format for moving the file to a specified character position within the current or following line.
-
On input, the file is moved to a specified character position and intervening character positions are ignored.
-
On output, the file is moved to a specified character position and blanks are inserted between the intervening character positions.
Component | Description |
---|---|
character-position |
Position. The value is converted to an integer and cannot be a negative value. |
4.4.4. E-format
E-format is a data format for representing a floating-point value.
-
On input, E-format is not yet supported.
-
On output, data are converted to a floating-point value and then saved to the stream. If the specified length of the E-format is less than or greater than the data length, the data-list item is extended or truncated. If the length is not specified, the data are saved to the stream as much as the length of the data-list item.
Component | Description |
---|---|
field-width |
Length of a float-point value. This value is converted to an integer and cannot be a negative value. |
4.4.5. F-format
F-format is a data format for representing a fixed-point value.
-
On input, F-format is not supported yet.
-
On output, data are converted to a fixed-point value and then saved to the stream.
Component | Description |
---|---|
field-width |
Length of a fixed-point value. The value is converted to an integer and cannot be a negative value. |
fractional-digits |
Mantissa length of a fixed-point. The value is converted to an integer and cannot be a negative value. The value cannot be greater than the value of field-width. If this value is omitted, it defaults to 0. |
scaling-factor |
Factor of a fixed-point. Scaling-factor multiplies the data value by 10 raised to the integer value of the scaling-factor. If the scaling-factor is a negative value, it divides the data value by 10. |
4.4.6. LINE format
LINE format is a control format for moving the position to a specified line.
-
On input, LINE format is not valid.
-
On output, the position is moved to a specified line. Blank lines are inserted between the current file position and the specified position.
Component | Description |
---|---|
line-number |
Specific line to move. The value is converted to an integer and cannot be a negative value. |
4.4.7. P-format
P format is a data format for representing a picture specification.
-
On input, the P format is not yet supported.
-
On output, data is converted to a specified picture format and then saved to the stream.
Component | Description |
---|---|
picture-specification |
Picture rule. For more information, refer to Picture Specification. |
4.4.8. PAGE format
PAGE format is a control format for starting a new page.
-
On input, PAGE format is not valid.
-
On output, a new page is started and the line is initialized to 1.
4.4.9. R-format
R format is a remote format for specifying the format-list of the FORMAT statement.
Component | Description |
---|---|
label-reference |
Label of a FORMAT statement. |
R-format is not supported when the label-reference is a label variable.
The following is an example of format-list of the FORMAT statement. In this example, R format is used in edit-directed output.
lbl1:FORMAT(A(4), X(2)); PUT EDIT(A,B,C,D)(A(2),F(15),R(lbl1),A);
The above PUT statement is the same as that of the below example.
PUT EDIT(A,B,C,D)(A(2),F(15),A(4),X(2),A);
4.4.10. SKIP format
SKIP format is a control format for skipping a line.
-
On input, the specified number of lines are skipped and the intervening lines are ignored.
-
On output, the specified number of lines are skipped, and blank lines are inserted between the current file line and the specified line.
Component | Description |
---|---|
relative-line |
Line to move. The value is converted to an integer and cannot be a negative value. |
4.4.11. X-format
X format is a control format for specifying a blank space.
-
On input, the specified number of characters are ignored.
-
On output, the specified number of blank characters are inserted.
Component | Description |
---|---|
field-width |
Number of characters to treat as blank characters, from the current position in the stream. The value is converted to an integer and cannot be a negative value. |