OpenVMS User's Manual
16.10 Writing to Files
To write to files, use the following procedure:
Step |
Action |
1
|
Open the file for writing.
|
2
|
Begin the write loop with a label.
File I/O is always done in a loop unless you are writing or reading
a single record.
|
3
|
Read the data to be written.
Use the INQUIRE command or the READ command to read data into a
symbol.
|
4
|
Test the data.
Check the symbol containing the data. If the symbol is null (for
example, if you press Return and enter no data on the line), you have
reached the end of the data to be written to the file and you should go
to the end of the loop. Otherwise, continue.
|
5
|
Write the data to the file.
Use the WRITE command to write the value of the symbol (one record)
to the file.
|
6
|
Return to the beginning of the loop.
You remain within the loop until there is no more data to be
written to the file.
|
7
|
End the loop and close the file.
|
The following command procedure writes data to the new file STATS.DAT.
If a file of that name exists, a new version is created.
$ ! Write a file
$ ON ERROR THEN EXIT ! Exit if the command
$ ! ! procedure cannot
$ ! ! open the file
$ OPEN/WRITE IN_FILE DISK4:[MURPHY]STATS.DAT ! Open the file
$ ON CONTROL_Y THEN GOTO END_WRITE ! Close the file if you
$ ! ! quit execution with
$ ! ! Ctrl/Y
$ ON ERROR THEN GOTO END_WRITE ! Close the file if an
$ ! ! error occurs
$WRITE: ! Begin the loop
$ INQUIRE STUFF "Input data" ! Prompt for input
$ IF STUFF .EQS. "" THEN GOTO END_WRITE ! Test for the end of
$ ! ! the file
$ WRITE IN_FILE STUFF ! Write to the file
$ GOTO WRITE ! Go to the beginning
$END_WRITE: ! End the loop
$ ! !
$ CLOSE IN_FILE ! Close the file
|
16.10.1 Creating Files with Unique File Names
To create a file with a unique name, use the F$SEARCH lexical function
to see if the name is already in the directory. (Refer to the lexical
function descriptions in the OpenVMS DCL Dictionary for more information about
F$SEARCH.)
This command procedure prompts the user for a file name, then uses the
F$SEARCH lexical function to search the default directory for the name.
If a file with that name already exists, control is passed to ERROR_1,
the procedure prints the message "The file already exists"
and control returns to the label GET_NAME. The procedure then prompts
for another file name as shown in the following example:
$ ! FILES.COM
$ !
$GET_NAME:
$ INQUIRE FILE "File" ! Prompt the user for a file name
$ IF F$SEARCH (FILE) .NES. "" ! Make sure the file name is unique
$ THEN
$ WRITE SYS$OUTPUT "The file already exists"
$ GOTO GET_NAME
$ ELSE
$ OPEN/WRITE IN_FILE 'FILE' ! Open the file with WRITE access
$ ENDIF
.
.
.
$ EXIT
|
16.11 Using the WRITE Command
The following sections describe how to use the WRITE command.
16.11.1 Specifying Data
When you specify data for the WRITE command, follow the rules for
character string expressions described in Chapter 14. You can
specify data in the following ways:
- Specify data to be written as a character string expression. The
WRITE command automatically substitutes symbols and lexical functions.
- Write a string to an output file as a literal character string. The
WRITE command does not perform symbol substitution on strings enclosed
in quotation marks.
- Combine literal strings with symbol names. To force symbol
substitution, place the entire string within quotation marks and use
double apostrophes before the symbol to identify it and a single
apostrophe following it.
Another way to combine literal strings
with symbol names is to insert a comma before and after the symbol,
place quotation marks around the delimited symbol, and enclose the
entire character string in quotation marks. For example:
$ WRITE OUTFILE "Count is ",COUNT,"."
|
- Use apostrophes in the WRITE command line to force symbol
substitution.
- Combine literal strings and lexical functions by using apostrophes
to force symbol substitution within character strings.
Example
$! Define symbols
$!
$ CREATED = "File created April 15, 1999"
$ COUNT = 4
$ P4 = "fourth parameter"
$!
$! Open the file DATA.OUT for writing
$!
$ OPEN/WRITE OUTFILE DISK4:[MURPHY]DATA.OUT
$!
$ WRITE OUTFILE CREATED (1)
$ WRITE OUTFILE "CREATED" (2)
$!
$ WRITE OUTFILE "Count is ''COUNT'." (3)
$ WRITE OUTFILE P'COUNT' (4)
$!
$ WRITE OUTFILE "Mode is ''f$mode()'" (5)
$!
$ CLOSE OUTFILE
$ TYPE DISK4:[MURPHY]DATA.OUT [Return] (6)
File created April 15, 1999
CREATED
Count is 4.
fourth parameter
Mode is INTERACTIVE
$
|
As you examine the example, note the following:
- Specifies the data to be written as a
character string expression.
- Writes the string CREATED to the
output file as a literal character string.
- Combines literal strings with symbol names.
- Uses an apostrophe in the WRITE command line
to force symbol substitution. In this example, the WRITE command
substitutes a value for the symbol COUNT and performs symbol
substitution on the resulting command string (P4).
- Combines literal strings and lexical
functions.
- Displays the data written to the output file
DATA.OUT by the preceding WRITE commands.
16.11.2 Using the /SYMBOL Qualifier
When the WRITE command writes a record, it positions the record pointer
after the record just written. The WRITE command can write a record
that is up to 2,048 bytes long.
Use the /SYMBOL qualifier to write a record if either of the following
conditions exist:
- The record is longer than 1,024 bytes.
- An expression in the WRITE command is longer than 255 bytes.
See the description of the WRITE command in the OpenVMS DCL Dictionary for more
information on writing long records.
16.11.3 Using the /UPDATE Qualifier
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.
16.12 Using 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.
|
The following 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.
16.12.1 Using the /END_OF_FILE Qualifier
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.
16.12.2 Using the /INDEX and /KEY Qualifiers
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.
16.12.3 Using the /DELETE Qualifier
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 about the /DELETE, /INDEX, and /KEY qualifiers,
refer to the description of the READ command in the OpenVMS DCL Dictionary.
16.13 Using the Close Command
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
|
16.14 Modifying Files
This section describes three methods of modifying files:
- Updating records
- Creating new output files
- Appending records
16.14.1 Updating Records
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.
16.14.2 Creating New 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.
Note
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.
|
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.
|
Examples: Modifying Records
- In the following example, the symbol NEW_FILE is written to a new
file:
$ ! No change
$ WRITE NEW_FILE RECORD
|
- In the following example, the INQUIRE command is used to write a
modified symbol to a new file:
$ ! Change
$ INQUIRE NEW_RECORD "New record"
$ WRITE NEW_FILE NEW_RECORD
|
- In the following example, a loop is used to write the symbol to a
new file:
$ ! 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:
|
Example: Creating Output Files
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
|
16.14.3 Appending Records to Files
Use the following procedure (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
|
|