OPEN EXTEND and REWRITE
OPEN OUTPUT always starts a file from scratch. Two other open modes let
you change a file that already exists.
OPEN EXTEND: add to the end
OPEN EXTEND positions you after the last record, and each WRITE adds a
new one. Logs, audit trails and "today's rejects" files that build up over
a day are typical uses.
What if the file does not exist yet? Normally the OPEN fails with status
35. Declare the file OPTIONAL in the SELECT and a missing file is
created instead, with status 05 to tell you so:
IDENTIFICATION DIVISION.
PROGRAM-ID. EXTDEMO.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT OPTIONAL AUDIT-FILE ASSIGN TO AUDITLOG
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS WS-AUDIT-STATUS.
DATA DIVISION.
FILE SECTION.
FD AUDIT-FILE.
01 AUDIT-REC PIC X(30).
WORKING-STORAGE SECTION.
01 WS-AUDIT-STATUS PIC XX.
PROCEDURE DIVISION.
OPEN EXTEND AUDIT-FILE
DISPLAY "OPEN EXTEND: " WS-AUDIT-STATUS
MOVE "RUN COMPLETED" TO AUDIT-REC
WRITE AUDIT-REC
CLOSE AUDIT-FILE
STOP RUN.
Run twice against a dataset that does not exist yet, it displays
OPEN EXTEND: 05 the first time and OPEN EXTEND: 00 the second, and
the dataset ends up with two RUN COMPLETED records. Remember that 05
is a success: a status check for this file must accept both 00 and
05. An 88-level with two values does that neatly:
01 WS-AUDIT-STATUS PIC XX.
88 AUDIT-OK VALUE "00" "05".
OPEN I-O and REWRITE: update in place
OPEN I-O opens a file for both reading and rewriting. REWRITE record
replaces the record you just read with the current contents of the
record area. The file keeps its records in the same order; only the one
record changes.
IDENTIFICATION DIVISION.
PROGRAM-ID. RWDEMO.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT CARD-FILE ASSIGN TO CARDS
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS WS-CARD-STATUS.
DATA DIVISION.
FILE SECTION.
FD CARD-FILE.
01 CARD-REC.
05 CARD-NO PIC X(4).
05 CARD-EXPIRY PIC 9(6).
05 CARD-STATE PIC X.
WORKING-STORAGE SECTION.
01 WS-CARD-STATUS PIC XX.
88 CARD-EOF VALUE "10".
PROCEDURE DIVISION.
OPEN I-O CARD-FILE
READ CARD-FILE
PERFORM UNTIL CARD-EOF
IF CARD-EXPIRY < 202609
MOVE "X" TO CARD-STATE
REWRITE CARD-REC
DISPLAY "EXPIRED " CARD-NO " " WS-CARD-STATUS
END-IF
READ CARD-FILE
END-PERFORM
CLOSE CARD-FILE
STOP RUN.
With CARD.MASTER holding
0001202712A
0002202508A
0003202609A
0004201911A
it displays EXPIRED 0002 00 and EXPIRED 0004 00, and afterwards the
dataset reads
0001202712A
0002202508X
0003202609A
0004201911X
The rules for REWRITE on a sequential file:
- The file must be open
I-O(otherwise status49). - The last operation on the file must have been a successful READ. A
REWRITE with no READ before it fails with status
43. - The record must keep its length. You change field contents, never
the layout. (With line sequential files, GnuCOBOL returns status
44if the new text is longer than the line it replaces.) - You cannot insert or delete records. For that, you write a new file, which is the subject of the next lesson.
Mainframe reality
On z/OS you would REWRITE a fixed-length disk dataset opened with
DISP=OLD (exclusive use). Line sequential files do not exist there;
they are used here so you can read the results.
On the job
Updating in place is fast, but there is no undo: if the program abends halfway through, half the file is updated. That is why jobs that REWRITE a file usually back it up in an earlier step, and why the big nightly updates use the old-master / new-master approach instead.
Your task
At the end of each day the warehouse flags items that need reordering.
Stock file, DD name STOCK, line sequential, opened I-O:
| Field | Picture | Positions |
|---|---|---|
STK-ITEM |
X(6) |
1–6 |
STK-DESC |
X(20) |
7–26 |
STK-QTY |
9(5) |
27–31 |
STK-REORDER |
9(5) |
32–36 |
STK-FLAG |
X: N normal, R on order |
37 |
Reorder log, DD name REORDLOG, line sequential, opened
EXTEND. It may not exist yet (first run of the month), so declare it
OPTIONAL. Layout (declared in the starter as LOG-REC): item, space,
description, space, quantity as Z(4)9.
For every item whose quantity is below its reorder level and which
is not already flagged R:
- set the flag to
Rand REWRITE the stock record, - append a record to the reorder log.
At the end display the number flagged:
FLAGGED: 002
If the stock file cannot be opened, display STOCK OPEN FAILED: and
the status, and stop with return code 12. Remember that 05 is a
successful OPEN for an optional file.