Use the /SYMBOL qualifier to write a record if either of the following conditions exist:
See the description of the WRITE command in the OpenVMS DCL Dictionary for more information on writing long records.
You can use the WRITE command with the /UPDATE qualifier to change a record rather than insert a new one. To use the /UPDATE qualifier, you must open the file for both reading and writing.
The following sections describe how to use the READ command.
Use the READ command to read a record and assign its contents to a symbol. You can use the READ command to read records that are less than or equal to 1,024 characters in length. To read data from a file, use the following procedure:
Step | Action |
---|---|
1 | Open the file for reading. |
2 |
Begin the read loop with a label.
File I/O is always done in a loop unless you are reading or writing a single record. |
3 |
Read the data from the file.
Use the READ command with the /END_OF_FILE qualifier to read a record and assign its contents to a symbol. The /END_OF_FILE qualifier causes DCL to pass control to the label specified by the /END_OF_FILE qualifier when you reach the end of the file. Generally, you specify the label that marks the end of the read loop. |
4 |
Process the data.
When you read a file sequentially, process the current record before reading the next one. |
5 |
Return to the beginning of the loop.
You remain in the loop until you reach the end of the file. |
6 | End the loop and close the file. |
This command procedure reads and processes each record in the file STATS.DAT. The procedure executes the READ command repeatedly until the end-of-file status is returned. Then, the procedure branches to the line labeled END_READ:
$ OPEN/READ INFILE DISK4:[MURPHY]STATS.DAT !Open the file $ ! $READ_DATA: !Begin the loop $ READ/END_OF_FILE=END_READ INFILE RECORD !Read a record; test for $ ! end of file $ ! Process the data . . . $ GOTO READ_DATA !Go to the beginning $ ! of the loop $END_READ: !End of loop $ CLOSE INFILE !Close the file $ EXIT
When you specify a symbol name for the READ command, the command interpreter places the symbol name in the local symbol table for the current command level. If you use the same symbol name for more than one READ command, each READ command redefines the value of the symbol name. For example, in the preceding example, the READ command reads a new record from the input file (STATS.DAT) each time through the loop. It then uses this record to redefine the value of the symbol RECORD.
When you read from files, you generally read and process each record until you reach the end of the file. By using the /END_OF_FILE qualifier with the READ command, you can construct a loop to read records from a file, process the records, and exit from the loop when you have finished reading all the records.
Note that the labels you specify for /END_OF_FILE qualifiers are subject to the same rules as labels specified for a GOTO command. (See Chapter 15 for more information on using the GOTO command.)
You should always use the /END_OF_FILE qualifier when you use the READ command in a loop. Otherwise, when the error condition indicating the end-of-file is returned by the OpenVMS Record Management Services (OpenVMS RMS), the command interpreter performs the error action specified by the current ON command. For example, OpenVMS RMS returns the error status %RMS-E-EOF. This causes a command procedure to exit unless the procedure has established its own error handling.
To read records randomly from indexed sequential files, use the READ command qualifiers /INDEX and /KEY. These qualifiers specify that a record should be read from the file by finding the specified key in the index and returning the record associated with that key. If you do not specify an index, the primary index (0) is used.
After you read a record randomly, you can read the remainder of the file sequentially by using READ commands without the /KEY or /INDEX qualifiers.
You can use the READ command with the /DELETE qualifier to delete records from indexed sequential files. The /DELETE qualifier causes a record to be deleted from a file after it has been read. Use the /DELETE qualifier with the /INDEX and /KEY qualifiers to delete a record specified by a given key.
For more information on the /DELETE, /INDEX, and /KEY qualifiers, see the description of the READ command in the OpenVMS DCL Dictionary.
The CLOSE command closes a file and deassigns the logical name created by the OPEN command. Be sure to close all files you open in a command procedure before the command procedure terminates. If you fail to close an open file, the file remains open when the command procedure terminates and the logical name assigned to the open file is not deleted from the process logical name table.
In the following example, the CLOSE command closes the file STATS.DAT and deassigns the logical name INFILE:
$ OPEN INFILE DISK4:[MURPHY]STATS.DAT . . . $ CLOSE INFILE
This section describes three methods of modifying files:
When you use the updating method to modify records, you can make minor changes to a small number of records in a file. Because this method does not allow you to change the size of a record or the number of records in the file, use it only for files with formatted records (for example, in a data file).
To make minor changes in a file, use this procedure:
Step | Action |
---|---|
1 | Open the file for both read and write access. |
2 | Use the READ command to read through the file until you reach the record that you want to modify. |
3 |
Modify the record.
In a sequential file, the text of this record must be exactly the same size as the original record. If the text of the modified record is shorter, pad the record with spaces, adding spaces to the end of the modified record until it is the same length as the original record. If the text of the modified record is longer, you need to create a new file. |
4 | Use the WRITE/UPDATE command to write the modified record back to the file. |
5 | Repeat steps 2 to 4 until you have changed all records you intend to change. |
6 |
Use the CLOSE command to close the file.
After you close the file, it contains the same version number as when you started, even though individual records have been changed. |
The following command procedure shows how to make changes to a sequential file by reading and updating individual records:
$! Open STATS.DAT and assign it the logical name FILE $! $ OPEN/READ/WRITE FILE DISK4:[MURPHY]STATS.DAT $ BEGIN_LOOP: $! Read the next record from FILE into the symbol RECORD $ READ/END_OF_FILE=END_LOOP FILE RECORD $! Display the record and see if the user wants to change it $! If yes, get the new record. If no, repeat loop $! $ PROMPT: $ WRITE SYS$OUTPUT RECORD $ INQUIRE/NOPUNCTUATION OK "Change? Y or N [Y] " $ IF OK .EQS. "N" THEN GOTO BEGIN_LOOP $ INQUIRE NEW_RECORD "New record" $! Compare the old and new records $! If old record is shorter than new record, issue an $! error message. If old record and new record are the $! same length, write the record. Otherwise pad the new $! record with spaces so it is correct length $! $ OLD_LEN = F$LENGTH(RECORD) $ NEW_LEN = F$LENGTH(NEW_RECORD) $ IF OLD_LEN .LT. NEW_LEN THEN GOTO ERROR $ IF OLD_LEN .EQ. NEW_LEN THEN GOTO WRITE_RECORD $ SPACES = " " $ PAD = F$EXTRACT(0,OLD_LEN-NEW_LEN,SPACES) $ NEW_RECORD = NEW_RECORD + PAD $! $ WRITE_RECORD: $ WRITE/UPDATE FILE NEW_RECORD $ GOTO BEGIN_LOOP $! $ ERROR: $ WRITE SYS$OUTPUT "Error -- New record is too long" $ GOTO PROMPT $! $ END_LOOP: $ CLOSE FILE $ EXIT
The system displays the record on the terminal and you are asked whether the record needs to be modified. If you choose to modify the record, a new record is read from the terminal and its length is compared to the length of the original record. If the original record is longer, extra spaces make the new record the same size. If the original record is shorter, the system displays an error message and you are again prompted for a new record.
The following sections describe how to create output files.
To make extensive changes to a file, open that file for read access and open a new file for write access. Because you are creating a new output file, you can modify the size of records, add records, delete records, or insert records.
The OPEN/WRITE command opens a new file for write access. The new file can have the same name as the original file and a version number one higher than the version number of the old file.
To ensure that the correct file is opened for reading, you must open the existing file for read access before you open the new version for write access.
To create files that you can modify, use the following procedure:
Step | Action |
---|---|
1 |
Open the file for read access.
This is the input file, the file you are modifying. |
2 |
Open a new file for write access.
This is the output file, the file that you are creating. If you give the output file the same name as the input file, the output file will have a version number one greater than the input file. |
3 |
Use the READ command to read each record from the file you are
modifying.
As you read each record from the original file, decide how the record is to be treated. See Section 16.20.4 for information on how records are handled. |
4 | Continue reading and processing records until you have finished. |
5 | Use the CLOSE command to close both the input file and the output file. |
In the following table, the symbol RECORD contains the record read from the original file:
If... | Then... |
---|---|
There is no change to the record | Write the same symbol to the new file. |
The record is changed | Use the INQUIRE command to read a different record into the symbol, then write the modified symbol to the new file. |
The record is deleted | Do not write the symbol to the new file. |
A record is inserted | Use a loop to read records into the symbol and to write the symbol to the new file. |
$ ! No change $ WRITE NEW_FILE RECORD
$ ! Change $ INQUIRE NEW_RECORD "New record" $ WRITE NEW_FILE NEW_RECORD
$ ! Insertion $LOOP: $ !Get new records to insert $ INQUIRE NEW_RECORD "New record" $ IF RECORD .EQS. "" THEN GOTO END_LOOP $ WRITE NEW_FILE NEW_RECORD $ GOTO LOOP $END_LOOP:
The following example shows a command procedure that reads a record from an input file, processes the record, and copies the record into an output file:
$! Open STATS.DAT for reading and assign it $! the logical name INFILE $! Open a new version of STATS.DAT for writing $! and assign it the logical name OUTFILE $! $ OPEN/READ INFILE DISK4:[MURPHY]STATS.DAT $ OPEN/WRITE OUTFILE DISK4:[MURPHY]STATS.DAT $! $ BEGIN_LOOP: $! Read the next record from INFILE into the symbol RECORD $! $ READ/END_OF_FILE=END_LOOP INFILE RECORD $! Display the record and see if the user wants to change it $! If yes, get the new record $! If no, write record directly to OUTFILE $! $ PROMPT: $ WRITE SYS$OUTPUT RECORD $ INQUIRE/NOPUNCTUATION OK "Change? Y or N [Y] " $ IF OK .EQS. "N" THEN GOTO WRITE_RECORD $ INQUIRE RECORD "New record" $! $ WRITE_RECORD: $ WRITE OUTFILE RECORD $ GOTO BEGIN_LOOP $! $! Close input and output files $ END_LOOP: $ CLOSE INFILE $ CLOSE OUTFILE $ EXIT
Use the following procedure to OPEN/APPEND command to append records to the end of existing files:
Step | Action |
---|---|
1 |
Use the OPEN command with the /APPEND qualifier to position the record
pointer at the end of the file.
The /APPEND qualifier does not create a new version of the file. |
2 | Use the WRITE command to write new data records. |
3 | Continue adding records until you are finished. |
4 | Use the CLOSE command to close the file. |
The following command procedure appends records to the end of the file named STATS.DAT:
$! Open STATS.DAT to append files and assign $! it the logical name FILE $! $ OPEN/APPEND FILE DISK4:[MURPHY]STATS.DAT $! $ BEGIN_LOOP: $! Obtain record to be appended and place this $! record in the symbol RECORD $! $ PROMPT: $ INQUIRE RECORD - "Enter new record (press RET to quit) " $ IF RECORD .EQS. "" THEN GOTO END_LOOP $! Write record to FILE $! $ WRITE FILE RECORD $ GOTO BEGIN_LOOP $! $! Close FILE and exit $! $ END_LOOP: $ CLOSE FILE $ EXIT
The following sections describe how to handle file I/O errors.
Use the /ERROR qualifier with the OPEN, READ, or WRITE command to suppress system error messages and to pass control to a specified label. If an error occurs during an input or output operation, the /ERROR qualifier overrides all other error-control mechanisms (except the /END_OF_FILE qualifier on the READ command).
The following example uses the /ERROR qualifier with the OPEN command:
$ OPEN/READ/ERROR=CHECK FILE CONTINGEN.DOC . . . $ CHECK: $ WRITE SYS$OUTPUT "Error opening file"
The OPEN command requests that the file CONTINGEN.DOC be opened for reading. If the file cannot be opened (for example, if the file does not exist), the OPEN command returns an error condition and transfers control to the CHECK label.
The error path specified by the /ERROR qualifier overrides the current ON condition established for the command level. If an error occurs and the target label is successfully given control, the reserved global symbol $STATUS retains the code for the error. You can use the F$MESSAGE lexical function in your error-handling routine to display the message in $STATUS.
In the following example, the lexical function F$MESSAGE is used to display the contents of the F$STATUS lexical:
$ OPEN/READ/ERROR=CHECK FILE 'P1' . . . $ CHECK: $ ERR_MESSAGE = F$MESSAGE($STATUS) $ WRITE SYS$OUTPUT "Error opening file: ",P1 $ WRITE SYS$OUTPUT ERR_MESSAGE . . .
If an error occurs while you are using the OPEN, READ, WRITE, or CLOSE command and you do not specify an error action, the current ON command action is taken.
When a READ command receives an end-of-file message, the error action is determined as follows:
The normal flow of execution in a command procedure is sequential: the commands in the procedure execute in order until the end of the file is reached. However, you can also control whether certain statements are executed or the conditions under which the procedure should continue executing.
The following sections discuss:
The IF command tests the value of an expression and executes a command or block of commands when the result of the expression is true. When the result of the expression is false, one of the following occurs:
DCL provides two distinct formats for the IF command. The first format executes a single command when the expression specified to the IF command is true, as discussed in Chapter 15
DCL also provides a block-structured IF format. The block-structured IF command executes more than one command if the expression specified is true and accepts an optional ELSE statement, which executes one or more commands if the expression is false.
To execute more than one command when an expression is true, specify the THEN command as a verb (a DCL command preceded by a dollar sign) and terminate the resulting block-structured statement with an ENDIF statement.
In the following example, the THEN statement is used as a verb:
$ IF expression $ THEN $ command $ command . . . $ ENDIF
To execute one or more commands when an expression is false, specify the ELSE statement as a verb and terminate the resulting block-structured statement with an ENDIF statement.
In the following example, the ELSE command is used as a verb:
$ IF expression $ THEN $ command $ command . . . $ ELSE $ command $ command . . . $ ENDIF
The following sections describe how to use command blocks. a
Command blocks can be executed in several ways, depending on whether you leave the commands in the same command procedure or put them in another command procedure and execute them there. The guidelines are as follows:
$ IF condition $ THEN command command . . . $ ENDIF
$ IF condition $ THEN @command_procedure $ ELSE command $ command $ ENDIF
$ IF not condition THEN GOTO END_LABEL . . . $END_LABEL:
You can execute a block of commands after the THEN command when the result of the IF expression is true. When you use a block of commands, place the THEN command as the first command on the line following the IF command.
In the following example, two SET TERMINAL commands execute and the procedure transfers control to the label PROCEED when F$MODE equals INTERACTIVE. When F$MODE does not equal INTERACTIVE, the procedure exits:
$ IF F$MODE () .EQS. "INTERACTIVE" $ THEN $ SET TERMINAL/DEVICE=VT200 $ SET TERMINAL/WIDTH=132 $ GOTO PROCEED $ ENDIF $ EXIT $PROCEED:
The following example illustrates how to use a block of commands with the IF command in conjunction with the ELSE command:
$ INQUIRE DEV "Device to check" $ IF F$GETDVI(DEV, "EXISTS") $ THEN $ WRITE SYS$OUTPUT "The device exists." $ SHOW DEVICE 'DEV' $ SET DEVICE/ERROR_LOGGING 'DEV' $ ELSE $ WRITE SYS$OUTPUT "The device does not exist." $ WRITE SYS$OUTPUT "Error logging has not been enabled." $ ENDIF $ EXIT
When the condition is true, the procedure writes a message to SYS$OUTPUT and executes the SHOW DEVICE and SET DEVICE commands. When the condition is not true, the procedure writes two messages to SYS$OUTPUT.
When you use the IF-THEN-ELSE language construct, observe the following restrictions:
The expression following the IF command can consist of one or more numeric constants, string literals, symbolic names, or lexical functions separated by logical, arithmetic, or string operators. An expression is true when it has one of the following values:
An expression is false when it has one of the following values:
When you write an expression for an IF command, adhere to the following rules:
The following examples illustrate expressions that can be used with the IF command. For additional examples, see the description of the IF command in the OpenVMS DCL Dictionary.
The following example uses a logical operator and executes only one command following the THEN statement. When the symbol CONT is not true, the procedure exits:
$ INQUIRE CONT "Do you want to continue [Y/N]" $ IF .NOT. CONT THEN EXIT . . .
The following example uses a symbol and a label within the IF expression:
$ INQUIRE CHANGE "Do you want to change the record [Y/N]" $ IF CHANGE THEN GOTO GET_CHANGE . . . $ GET_CHANGE: . . .
6489P031.HTM OSSG Documentation 22-NOV-1996 13:17:23.15
Copyright © Digital Equipment Corporation 1996. All Rights Reserved.