| Verb | Description | Example |
|---|---|---|
| OPEN INPUT | Open an existing file for reading. | OPEN INPUT CUSTOMER-FILE. |
| OPEN OUTPUT | Create a file for writing. An existing file is replaced. | OPEN OUTPUT REPORT-FILE. |
| OPEN I-O | Open an existing file for READ and REWRITE. | OPEN I-O CUSTOMER-FILE. |
| OPEN EXTEND | Open an existing file and write records after the last one. | OPEN EXTEND LOG-FILE. |
| READ | Read the next record. AT END runs when none remain. | READ CUSTOMER-FILE
AT END MOVE "Y" TO EOF-FLAG |
| READ NEXT | On a sequential file, this is the same as READ. | READ CUSTOMER-FILE NEXT. |
| WRITE | Add a new record. | WRITE CUSTOMER-RECORD FROM WORK-RECORD. |
| REWRITE | Replace the record you just read. The file must be open I-O. | REWRITE CUSTOMER-RECORD. |
| CLOSE | Finish the file and release it. | CLOSE CUSTOMER-FILE. |
The OPEN statement establishes a connection between a COBOL program and a file, making it available for processing. It is the first operation performed on a file before any other file operations can be executed. The mode used in the OPEN statement determines what operations are permitted on the file.
1234OPEN [INPUT file-name-1 [file-name-2] ...] [OUTPUT file-name-3 [file-name-4] ...] [I-O file-name-5 [file-name-6] ...] [EXTEND file-name-7 [file-name-8] ...]
Multiple files can be opened in a single OPEN statement, and different files can be opened with different modes in the same statement.
| Mode | Description | Permitted Operations | File State |
|---|---|---|---|
| INPUT | Opens an existing file for reading | READ | File must exist |
| OUTPUT | Creates a new file for writing | WRITE | Any existing file is deleted |
| I-O | Opens an existing file for both reading and writing | READ, REWRITE, DELETE | File must exist |
| EXTEND | Opens an existing file for adding records at the end | WRITE (appends to end) | File must exist |
123456789101112131415161718* Opening a single file for reading OPEN INPUT CUSTOMER-FILE. * Opening multiple files with different modes OPEN INPUT CUSTOMER-MASTER OUTPUT REPORT-FILE I-O TRANSACTION-FILE. * Opening a file for appending records OPEN EXTEND LOG-FILE. * Combined with file status checking OPEN INPUT CUSTOMER-FILE IF CUSTOMER-FILE-STATUS = "00" PERFORM PROCESS-CUSTOMERS ELSE PERFORM FILE-ERROR-ROUTINE END-IF.
| Error | Status Code | Cause | Solution |
|---|---|---|---|
| File not found | "35" | Opening a non-existent file with INPUT or I-O | Create file first or handle error |
| Access denied | "37" | Insufficient permissions | Fix file permissions |
| File already open | "41" | Attempting to open a file already opened | Close file before reopening |
| File attribute conflict | "39" | File characteristics don't match FD | Ensure file and FD match |
The READ statement retrieves the next record from a sequential file. Each successful READ advances the file position to the following record. For sequential files, records are read in the order they were written, from the beginning to the end of the file.
1234READ file-name [NEXT] [RECORD] [INTO identifier] [AT END imperative-statement-1] [NOT AT END imperative-statement-2] [END-READ]
123456789101112131415161718192021* Basic READ READ CUSTOMER-FILE AT END SET END-OF-FILE TO TRUE END-READ. * READ with both AT END and NOT AT END READ EMPLOYEE-FILE AT END DISPLAY "End of file reached" MOVE "Y" TO EOF-FLAG NOT AT END ADD 1 TO RECORD-COUNT PERFORM PROCESS-EMPLOYEE END-READ. * READ INTO a working-storage area READ TRANSACTION-FILE INTO TRANSACTION-WORK-RECORD AT END MOVE "Y" TO EOF-FLAG END-READ.
The INTO clause is particularly useful when you want to keep the file record separate from your working data, allowing you to maintain the original record while modifying a copy.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273IDENTIFICATION DIVISION. PROGRAM-ID. SEQREAD. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO "CUSTOMER.DAT" ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS CUSTOMER-STATUS. DATA DIVISION. FILE SECTION. FD CUSTOMER-FILE RECORD CONTAINS 80 CHARACTERS. 01 CUSTOMER-RECORD. 05 CUST-ID PIC 9(5). 05 CUST-NAME PIC X(30). 05 CUST-ADDRESS PIC X(40). 05 CUST-TYPE PIC X. 88 RETAIL VALUE "R". 88 WHOLESALE VALUE "W". 88 GOVERNMENT VALUE "G". 05 FILLER PIC X(4). WORKING-STORAGE SECTION. 01 FILE-VARIABLES. 05 CUSTOMER-STATUS PIC XX. 05 EOF-FLAG PIC X VALUE "N". 88 END-OF-FILE VALUE "Y". 01 COUNTERS. 05 RETAIL-COUNT PIC 9(5) VALUE ZEROS. 05 WHOLESALE-COUNT PIC 9(5) VALUE ZEROS. 05 GOVERNMENT-COUNT PIC 9(5) VALUE ZEROS. 05 TOTAL-COUNT PIC 9(5) VALUE ZEROS. PROCEDURE DIVISION. MAIN-PROCESS. PERFORM INITIALIZATION PERFORM PROCESS-RECORDS UNTIL END-OF-FILE PERFORM FINALIZATION STOP RUN. INITIALIZATION. OPEN INPUT CUSTOMER-FILE IF CUSTOMER-STATUS NOT = "00" DISPLAY "Error opening file: " CUSTOMER-STATUS MOVE "Y" TO EOF-FLAG END-IF. PROCESS-RECORDS. READ CUSTOMER-FILE AT END MOVE "Y" TO EOF-FLAG NOT AT END ADD 1 TO TOTAL-COUNT EVALUATE TRUE WHEN RETAIL ADD 1 TO RETAIL-COUNT WHEN WHOLESALE ADD 1 TO WHOLESALE-COUNT WHEN GOVERNMENT ADD 1 TO GOVERNMENT-COUNT END-EVALUATE END-READ. FINALIZATION. CLOSE CUSTOMER-FILE DISPLAY "Processing complete" DISPLAY "Total records: " TOTAL-COUNT DISPLAY "Retail customers: " RETAIL-COUNT DISPLAY "Wholesale customers: " WHOLESALE-COUNT DISPLAY "Government customers: " GOVERNMENT-COUNT.
This example demonstrates a typical sequential file processing pattern. It reads customer records, counts records by customer type, and displays totals when complete. The processing loop continues until the end of file is reached.
There are two common methods to detect the end of a file:
123456789101112131415161718192021* Method 1: Using AT END READ CUSTOMER-FILE AT END MOVE "Y" TO EOF-FLAG END-READ. * Method 2: Checking file status READ CUSTOMER-FILE IF CUSTOMER-STATUS = "10" MOVE "Y" TO EOF-FLAG END-IF. * Combined approach (most robust) READ CUSTOMER-FILE AT END MOVE "Y" TO EOF-FLAG END-READ IF CUSTOMER-STATUS NOT = "00" AND CUSTOMER-STATUS NOT = "10" DISPLAY "Error reading file: " CUSTOMER-STATUS PERFORM ERROR-ROUTINE END-IF.
The WRITE statement adds new records to a file. For sequential files, each WRITE operation adds a record at the current position, which is typically at the end of the file. The position advances automatically after each WRITE, making records appear in the file in the same order they were written.
12345WRITE record-name [FROM identifier-1] [AFTER|BEFORE ADVANCING {identifier-2 | integer | PAGE}] [AT END-OF-PAGE imperative-statement-1] [NOT AT END-OF-PAGE imperative-statement-2] [END-WRITE]
12345678910111213141516* Basic WRITE WRITE CUSTOMER-RECORD. * WRITE with FROM clause WRITE CUSTOMER-RECORD FROM CUSTOMER-WORK-AREA. * WRITE with file status checking WRITE EMPLOYEE-RECORD IF FILE-STATUS NOT = "00" PERFORM ERROR-ROUTINE END-IF. * WRITE for print files with line control WRITE REPORT-LINE AFTER ADVANCING 2 LINES. WRITE REPORT-LINE BEFORE ADVANCING PAGE. WRITE REPORT-LINE AFTER ADVANCING LINE-COUNT LINES.
The FROM clause is particularly useful as it allows you to write from a working-storage area while preserving the contents of the file record area for subsequent operations.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980IDENTIFICATION DIVISION. PROGRAM-ID. FILEWRITE. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT OUTPUT-FILE ASSIGN TO "NEWDATA.DAT" ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS FILE-STATUS. DATA DIVISION. FILE SECTION. FD OUTPUT-FILE RECORD CONTAINS 80 CHARACTERS. 01 OUTPUT-RECORD. 05 REC-TYPE PIC X. 05 REC-ID PIC 9(5). 05 REC-NAME PIC X(30). 05 REC-AMOUNT PIC 9(7)V99. 05 REC-DATE PIC 9(8). 05 FILLER PIC X(28). WORKING-STORAGE SECTION. 01 FILE-STATUS PIC XX. 01 WS-RECORD. 05 WS-TYPE PIC X. 05 WS-ID PIC 9(5). 05 WS-NAME PIC X(30). 05 WS-AMOUNT PIC 9(7)V99. 05 WS-DATE PIC 9(8). 05 FILLER PIC X(28). 01 EOF-FLAG PIC X VALUE "N". 88 END-OF-DATA VALUE "Y". PROCEDURE DIVISION. MAIN-PROCESS. PERFORM INITIALIZATION PERFORM PROCESS-RECORDS UNTIL END-OF-DATA PERFORM TERMINATION STOP RUN. INITIALIZATION. OPEN OUTPUT OUTPUT-FILE IF FILE-STATUS NOT = "00" DISPLAY "Error opening output file: " FILE-STATUS MOVE "Y" TO EOF-FLAG END-IF. PROCESS-RECORDS. DISPLAY "Enter record type (or X to exit): " ACCEPT WS-TYPE IF WS-TYPE = "X" MOVE "Y" TO EOF-FLAG ELSE DISPLAY "Enter ID: " ACCEPT WS-ID DISPLAY "Enter Name: " ACCEPT WS-NAME DISPLAY "Enter Amount: " ACCEPT WS-AMOUNT DISPLAY "Enter Date (YYYYMMDD): " ACCEPT WS-DATE WRITE OUTPUT-RECORD FROM WS-RECORD IF FILE-STATUS NOT = "00" DISPLAY "Error writing record: " FILE-STATUS PERFORM ERROR-ROUTINE END-IF END-IF. TERMINATION. CLOSE OUTPUT-FILE DISPLAY "File processing complete.". ERROR-ROUTINE. DISPLAY "File operation failed with status: " FILE-STATUS DISPLAY "Processing terminated." MOVE "Y" TO EOF-FLAG.
This example demonstrates creating a sequential file by accepting user input and writing records until the user enters 'X' for the record type. It shows proper file opening, writing with the FROM clause, status checking, and closing.
| OPEN Mode | WRITE Behavior | Common Use Case |
|---|---|---|
| OUTPUT | Writes records to a new file, starting at the beginning | Creating new files, replacing existing files |
| EXTEND | Adds records to the end of an existing file | Appending to log files, adding to existing data |
| I-O | WRITE is not allowed for sequential files in I-O mode | N/A (Use REWRITE instead for updates) |
| INPUT | WRITE is not allowed in INPUT mode | N/A (Change to OUTPUT or EXTEND mode) |
| Status Code | Error Condition | Solution |
|---|---|---|
| "24" | Boundary violation (record size) | Check record size matches FD |
| "34" | Disk full or quota exceeded | Free disk space or increase quota |
| "48" | WRITE not supported in current open mode | Change OPEN mode to OUTPUT or EXTEND |
| "90" | Other I/O error during write | Check system logs, disk hardware |
The CLOSE statement terminates the connection between a COBOL program and a file, releasing any resources associated with the file. It is important to properly close all files when processing is complete to ensure data integrity and prevent resource leaks.
1CLOSE file-name-1 [file-name-2] ... [WITH LOCK]
12345678910111213141516* Closing a single file CLOSE CUSTOMER-FILE. * Closing multiple files CLOSE CUSTOMER-FILE TRANSACTION-FILE REPORT-FILE. * Closing with lock CLOSE SENSITIVE-DATA-FILE WITH LOCK. * Closing with file status checking CLOSE INVENTORY-FILE IF INVENTORY-STATUS NOT = "00" PERFORM CLOSE-ERROR-ROUTINE END-IF.
When a file is closed, the following actions typically occur:
Proper closing is essential, especially for output files, to ensure all data is written to the physical device and file integrity is maintained.
While CLOSE operations typically succeed, some errors can occur:
| Status Code | Error Condition | Possible Cause |
|---|---|---|
| "42" | File not open | Attempting to close a file that isn't open |
| "90-99" | Physical I/O error | Hardware issue during final write operations |
| "34" | Disk full | Not enough space to write final buffers |
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980IDENTIFICATION DIVISION. PROGRAM-ID. FILEOPS. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT INPUT-FILE ASSIGN TO "INPUT.DAT" ORGANIZATION IS SEQUENTIAL FILE STATUS IS INPUT-STATUS. SELECT OUTPUT-FILE ASSIGN TO "OUTPUT.DAT" ORGANIZATION IS SEQUENTIAL FILE STATUS IS OUTPUT-STATUS. DATA DIVISION. FILE SECTION. FD INPUT-FILE RECORD CONTAINS 80 CHARACTERS. 01 INPUT-RECORD PIC X(80). FD OUTPUT-FILE RECORD CONTAINS 80 CHARACTERS. 01 OUTPUT-RECORD PIC X(80). WORKING-STORAGE SECTION. 01 FILE-STATUSES. 05 INPUT-STATUS PIC XX. 05 OUTPUT-STATUS PIC XX. 01 EOF-FLAG PIC X VALUE "N". 88 END-OF-FILE VALUE "Y". PROCEDURE DIVISION. MAIN-PROCESS. PERFORM INITIALIZATION IF INPUT-STATUS = "00" AND OUTPUT-STATUS = "00" PERFORM PROCESS-FILES UNTIL END-OF-FILE END-IF PERFORM TERMINATION STOP RUN. INITIALIZATION. OPEN INPUT INPUT-FILE IF INPUT-STATUS NOT = "00" DISPLAY "Error opening input file: " INPUT-STATUS MOVE "Y" TO EOF-FLAG ELSE OPEN OUTPUT OUTPUT-FILE IF OUTPUT-STATUS NOT = "00" DISPLAY "Error opening output file: " OUTPUT-STATUS MOVE "Y" TO EOF-FLAG * Close the file that was successfully opened CLOSE INPUT-FILE END-IF END-IF. PROCESS-FILES. READ INPUT-FILE AT END MOVE "Y" TO EOF-FLAG NOT AT END MOVE INPUT-RECORD TO OUTPUT-RECORD WRITE OUTPUT-RECORD IF OUTPUT-STATUS NOT = "00" DISPLAY "Error writing record: " OUTPUT-STATUS MOVE "Y" TO EOF-FLAG END-IF END-READ. TERMINATION. * Close files regardless of processing status IF INPUT-STATUS NOT = "42" * Not "file not open" CLOSE INPUT-FILE END-IF IF OUTPUT-STATUS NOT = "42" * Not "file not open" CLOSE OUTPUT-FILE END-IF DISPLAY "Processing complete." DISPLAY "Input status: " INPUT-STATUS DISPLAY "Output status: " OUTPUT-STATUS.
This example demonstrates robust file handling with proper opening, error detection, and closing. Note that the termination routine closes files even if errors occurred during processing, ensuring that resources are properly released.
File status checking is an essential aspect of COBOL file handling. The file status is a two-character field that contains the result of each file operation. By checking this status after each operation, programs can detect and handle errors or exceptional conditions.
File status is defined in two places:
1234567891011121314ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO "CUSTOMER.DAT" ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS CUSTOMER-STATUS. DATA DIVISION. WORKING-STORAGE SECTION. 01 CUSTOMER-STATUS PIC XX. 88 STATUS-OK VALUE "00". 88 END-OF-FILE VALUE "10". 88 FILE-NOT-FOUND VALUE "35".
Using 88-level condition names makes the code more readable when checking for specific status conditions.
| Status | Meaning | Operations |
|---|---|---|
| "00" | Successful completion | All operations |
| "10" | End of file reached | READ |
| "35" | File not found | OPEN INPUT, OPEN I-O |
| "37" | File access denied (permissions) | OPEN |
| "39" | File attribute mismatch | OPEN |
| "41" | File already open | OPEN |
| "42" | File not open | CLOSE, READ, WRITE |
| "46" | Read beyond file end | READ |
| "47" | Input/output error | OPEN, CLOSE, READ, WRITE |
| "48" | File not open in correct mode | READ, WRITE |
| "93" | Resource unavailable | OPEN |
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109IDENTIFICATION DIVISION. PROGRAM-ID. STATUSCHK. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT DATA-FILE ASSIGN TO "DATA.DAT" ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS DATA-STATUS. DATA DIVISION. FILE SECTION. FD DATA-FILE RECORD CONTAINS 100 CHARACTERS. 01 DATA-RECORD PIC X(100). WORKING-STORAGE SECTION. 01 FILE-VARIABLES. 05 DATA-STATUS PIC XX. 88 STATUS-OK VALUE "00". 88 END-OF-FILE VALUE "10". 88 FILE-NOT-FOUND VALUE "35". 05 EOF-FLAG PIC X VALUE "N". 88 AT-END VALUE "Y". 05 ERROR-FLAG PIC X VALUE "N". 88 ERROR-OCCURRED VALUE "Y". PROCEDURE DIVISION. MAIN-PROCESS. PERFORM INITIALIZE-PROCESSING IF NOT ERROR-OCCURRED PERFORM PROCESS-DATA UNTIL AT-END OR ERROR-OCCURRED END-IF PERFORM TERMINATE-PROCESSING STOP RUN. INITIALIZE-PROCESSING. PERFORM OPEN-DATA-FILE IF ERROR-OCCURRED DISPLAY "Cannot continue processing due to file error" END-IF. PROCESS-DATA. PERFORM READ-DATA-RECORD IF NOT AT-END AND NOT ERROR-OCCURRED PERFORM PROCESS-RECORD END-IF. TERMINATE-PROCESSING. PERFORM CLOSE-DATA-FILE DISPLAY "Processing complete". OPEN-DATA-FILE. OPEN INPUT DATA-FILE PERFORM CHECK-FILE-STATUS. READ-DATA-RECORD. READ DATA-FILE AT END SET AT-END TO TRUE END-READ PERFORM CHECK-FILE-STATUS. CLOSE-DATA-FILE. CLOSE DATA-FILE PERFORM CHECK-FILE-STATUS. PROCESS-RECORD. * Process the current record DISPLAY DATA-RECORD. CHECK-FILE-STATUS. EVALUATE DATA-STATUS WHEN "00" * Operation successful - no action needed CONTINUE WHEN "10" * End of file - not an error for READ IF NOT AT-END SET AT-END TO TRUE END-IF WHEN "35" DISPLAY "File not found" SET ERROR-OCCURRED TO TRUE WHEN "37" DISPLAY "Access denied - check permissions" SET ERROR-OCCURRED TO TRUE WHEN "39" DISPLAY "Attribute mismatch - check file definition" SET ERROR-OCCURRED TO TRUE WHEN "41" DISPLAY "File already open" SET ERROR-OCCURRED TO TRUE WHEN "42" DISPLAY "File not open" SET ERROR-OCCURRED TO TRUE WHEN "46" DISPLAY "Read beyond end of file" SET ERROR-OCCURRED TO TRUE WHEN "47" DISPLAY "I/O error - check hardware" SET ERROR-OCCURRED TO TRUE WHEN "48" DISPLAY "File not open in correct mode" SET ERROR-OCCURRED TO TRUE WHEN OTHER DISPLAY "Unexpected file status: " DATA-STATUS SET ERROR-OCCURRED TO TRUE END-EVALUATE.
This example demonstrates a comprehensive approach to file status checking. A centralized CHECK-FILE-STATUS routine examines the status after each file operation and takes appropriate action based on the specific status code.
Some COBOL implementations support an extended file status, which provides more detailed information about file operations. The extended status typically consists of:
123456789101112131415161718ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO CUSTFILE FILE STATUS IS CUSTOMER-STATUS. DATA DIVISION. WORKING-STORAGE SECTION. * Standard file status 01 CUSTOMER-STATUS. 05 PRIMARY-STATUS PIC XX. 05 SECONDARY-STATUS PIC XXX. * Example usage IF PRIMARY-STATUS NOT = "00" DISPLAY "Error: " PRIMARY-STATUS "-" SECONDARY-STATUS END-IF.
The exact format of extended file status varies by compiler. Check your compiler documentation for specific details about extended status codes.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125IDENTIFICATION DIVISION. PROGRAM-ID. FILELOG. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT DATA-FILE ASSIGN TO "DATA.DAT" ORGANIZATION IS SEQUENTIAL FILE STATUS IS DATA-STATUS. SELECT LOG-FILE ASSIGN TO "FILELOG.TXT" ORGANIZATION IS SEQUENTIAL FILE STATUS IS LOG-STATUS. DATA DIVISION. FILE SECTION. FD DATA-FILE RECORD CONTAINS 100 CHARACTERS. 01 DATA-RECORD PIC X(100). FD LOG-FILE RECORD CONTAINS 80 CHARACTERS. 01 LOG-RECORD PIC X(80). WORKING-STORAGE SECTION. 01 FILE-VARIABLES. 05 DATA-STATUS PIC XX. 05 LOG-STATUS PIC XX. 05 CURRENT-DATE-TIME. 10 CURRENT-DATE. 15 CURRENT-YEAR PIC 9(4). 15 CURRENT-MONTH PIC 9(2). 15 CURRENT-DAY PIC 9(2). 10 CURRENT-TIME. 15 CURRENT-HOUR PIC 9(2). 15 CURRENT-MINUTE PIC 9(2). 15 CURRENT-SECOND PIC 9(2). 15 CURRENT-MS PIC 9(2). 05 TIMESTAMP PIC X(19). 05 MESSAGE PIC X(60). PROCEDURE DIVISION. MAIN-PROCESS. OPEN OUTPUT LOG-FILE IF LOG-STATUS NOT = "00" DISPLAY "Could not open log file: " LOG-STATUS ELSE * Now try to work with the data file PERFORM LOG-MESSAGE "Starting file processing" OPEN INPUT DATA-FILE IF DATA-STATUS NOT = "00" PERFORM LOG-ERROR "OPEN" "DATA-FILE" DATA-STATUS ELSE PERFORM PROCESS-FILE CLOSE DATA-FILE PERFORM LOG-FILE-STATUS "CLOSE" "DATA-FILE" DATA-STATUS END-IF PERFORM LOG-MESSAGE "Processing complete" CLOSE LOG-FILE END-IF STOP RUN. PROCESS-FILE. PERFORM LOG-MESSAGE "Reading records" PERFORM UNTIL DATA-STATUS NOT = "00" READ DATA-FILE AT END EXIT PERFORM END-READ IF DATA-STATUS = "00" * Process the record CONTINUE ELSE IF DATA-STATUS NOT = "10" PERFORM LOG-ERROR "READ" "DATA-FILE" DATA-STATUS EXIT PERFORM END-IF END-PERFORM. LOG-FILE-STATUS. * Parameters: operation, file-name, status MOVE FUNCTION CURRENT-DATE TO CURRENT-DATE-TIME STRING CURRENT-YEAR "-" CURRENT-MONTH "-" CURRENT-DAY " " CURRENT-HOUR ":" CURRENT-MINUTE ":" CURRENT-SECOND INTO TIMESTAMP STRING TIMESTAMP " " FUNCTION TRIM(FUNCTION-ID-1) " " FUNCTION TRIM(FUNCTION-ID-2) " Status: " FUNCTION-ID-3 INTO MESSAGE PERFORM WRITE-LOG-RECORD. LOG-ERROR. * Parameters: operation, file-name, status MOVE FUNCTION CURRENT-DATE TO CURRENT-DATE-TIME STRING CURRENT-YEAR "-" CURRENT-MONTH "-" CURRENT-DAY " " CURRENT-HOUR ":" CURRENT-MINUTE ":" CURRENT-SECOND INTO TIMESTAMP STRING TIMESTAMP " ERROR: " FUNCTION TRIM(FUNCTION-ID-1) " " FUNCTION TRIM(FUNCTION-ID-2) " Failed with status: " FUNCTION-ID-3 INTO MESSAGE PERFORM WRITE-LOG-RECORD. LOG-MESSAGE. * Parameters: message-text MOVE FUNCTION CURRENT-DATE TO CURRENT-DATE-TIME STRING CURRENT-YEAR "-" CURRENT-MONTH "-" CURRENT-DAY " " CURRENT-HOUR ":" CURRENT-MINUTE ":" CURRENT-SECOND INTO TIMESTAMP STRING TIMESTAMP " " FUNCTION TRIM(FUNCTION-ID-1) INTO MESSAGE PERFORM WRITE-LOG-RECORD. WRITE-LOG-RECORD. MOVE MESSAGE TO LOG-RECORD WRITE LOG-RECORD IF LOG-STATUS NOT = "00" DISPLAY "Error writing to log: " LOG-STATUS END-IF.
This example demonstrates a more advanced approach with a dedicated logging system for file operations. It creates timestamped log entries for each file operation, including the operation type, file name, and status code, providing a detailed audit trail of file processing.
OPEN, READ, and WRITE use the name from SELECT. They do not use the dataset name. SELECT CUST-FILE ASSIGN TO CUSTFILE means the program calls the file CUST-FILE, and the system looks up CUSTFILE. On z/OS that name is the DD statement in the JCL. In GnuCOBOL the same spot is usually a file name in quotes, such as ASSIGN TO "CUSTOMER.DAT".
12345FILE-CONTROL. SELECT CUST-FILE ASSIGN TO CUSTFILE ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS CUST-STAT.
The name in OPEN has to be the SELECT name. If CUSTFILE has no matching DD, or the quoted file name does not exist when you OPEN INPUT, the file status is 35.
ORGANIZATION IS SEQUENTIAL means the records stay in the order they were written. The first WRITE is the first record. The next READ returns the next record. There is no key. If you leave the clause out, Enterprise COBOL and GnuCOBOL both treat the file as sequential.
These are the organization values you will see on a SELECT:
ACCESS MODE IS SEQUENTIAL means each READ and each WRITE moves one record forward from the current position. You cannot ask for a particular record. A file with ORGANIZATION IS SEQUENTIAL uses this mode even if you omit the clause.
ORGANIZATION IS LINE SEQUENTIAL describes a text file. The record is one line. A newline marks the end. On WRITE, trailing spaces in the record are not stored. On READ, the newline is removed and the rest of the FD record is padded with spaces.
GnuCOBOL uses this organization, and so does IBM COBOL for Linux, AIX, and Windows. Enterprise COBOL for z/OS does not. A sequential dataset on z/OS is ORGANIZATION IS SEQUENTIAL. The record length is the length in the FD, and the file does not store a newline after each record.
WRITE AFTER ADVANCING PAGE on a line sequential file writes a form-feed character and then the line. On a z/OS print file the same phrase skips to the next page through carriage control. OPEN EXTEND still means append. If the file is missing and the SELECT does not say OPTIONAL, the status is 35.
1234SELECT REPORT-FILE ASSIGN TO "REPORT.TXT" ORGANIZATION IS LINE SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS REPORT-STAT.
OPEN INPUT opens an existing file for READ. The current position is the first record. WRITE and REWRITE are not allowed. If you issue them, the file status is 48.
The file has to be there. Status 35 means it was not found. Put OPTIONAL in front of the file name on the SELECT when a missing file should be treated as empty. OPEN INPUT then returns status 05, and the first READ hits AT END with status 10.
12345678SELECT OPTIONAL CUST-FILE ASSIGN TO CUSTFILE ORGANIZATION IS SEQUENTIAL FILE STATUS IS CUST-STAT. * OPEN INPUT CUST-FILE IF CUST-STAT = "35" DISPLAY "FILE NOT FOUND" END-IF
OPEN OUTPUT starts a new file for WRITE. If a file with that name already exists, the records that were in it are discarded. READ is not allowed. On z/OS the ASSIGN name is still the DD name. DISP on that DD controls whether the dataset itself is new or reused. The COBOL rule is the same either way: the first WRITE goes at the start of the file.
1234567OPEN OUTPUT CUST-FILE IF CUST-STAT NOT = "00" DISPLAY "OPEN OUTPUT FAILED " CUST-STAT STOP RUN END-IF WRITE CUST-REC FROM WORK-REC CLOSE CUST-FILE
OPEN EXTEND opens an existing file and positions after the last record. WRITE appends. READ is not allowed. This is the mode for a log, or for adding a batch of records to a file you must not empty.
The file must already exist, unless the SELECT says OPTIONAL. A missing file that is not optional returns status 35. OPTIONAL plus OPEN EXTEND creates the file, and the status on that open is 05. OUTPUT would have thrown the old records away. EXTEND keeps them.
123456789OPEN EXTEND LOG-FILE IF LOG-STAT = "35" DISPLAY "LOG FILE MISSING" STOP RUN END-IF IF LOG-STAT = "00" OR "05" WRITE LOG-REC FROM LOG-LINE END-IF CLOSE LOG-FILE
On a sequential file, the COBOL READ statement and READ NEXT are the same operation. Both return the next record and move the current position forward. NEXT names the direction. You need the word NEXT when an indexed file uses ACCESS MODE IS DYNAMIC and you want the following record in key order. A sequential file has no key, so READ CUST-FILE and READ CUST-FILE NEXT do the same thing.
AT END runs when no record remains. The file status is then 10. NOT AT END runs when a record was returned. INTO copies that record into a working-storage item as well as leaving it in the FD record area. There is no READ PREVIOUS for a sequential file.
12345678PERFORM UNTIL CUST-STAT = "10" READ CUST-FILE NEXT INTO WORK-REC AT END CONTINUE NOT AT END DISPLAY CUST-NAME END-READ END-PERFORM
REWRITE replaces the record you just read. The file has to be open I-O, and the last successful statement on that file has to be a READ. Change the record area, or use FROM to take the new value from working storage, then REWRITE the FD record name. You rewrite the record you just read. You do not search for a different one.
Status 43 means there is no current record, usually because the READ failed or you never issued one. Status 48 means the file is not open in a mode that allows the update. Status 44 means the rewritten record length is not allowed. Sequential organization has no DELETE. DELETE is for indexed and relative files.
12345678910OPEN I-O CUST-FILE READ CUST-FILE AT END CONTINUE END-READ IF CUST-STAT = "00" MOVE NEW-BAL TO CUST-BAL REWRITE CUST-REC END-IF CLOSE CUST-FILE
COBOL file handling for a sequential file is the same four steps every time. Name the file in SELECT, describe the record under an FD, OPEN it, then READ or WRITE until you CLOSE. This program reads a sequential file with OPEN INPUT and the READ statement.
12345678910111213141516171819202122232425262728293031323334IDENTIFICATION DIVISION. PROGRAM-ID. READSEQ. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUST-FILE ASSIGN TO CUSTFILE ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS CUST-STAT. DATA DIVISION. FILE SECTION. FD CUST-FILE RECORD CONTAINS 29 CHARACTERS. 01 CUST-REC. 05 CUST-NAME PIC X(20). 05 CUST-BAL PIC 9(7)V99. WORKING-STORAGE SECTION. 01 CUST-STAT PIC XX. PROCEDURE DIVISION. OPEN INPUT CUST-FILE IF CUST-STAT NOT = "00" DISPLAY "OPEN FAILED " CUST-STAT STOP RUN END-IF PERFORM UNTIL CUST-STAT = "10" READ CUST-FILE NEXT AT END CONTINUE NOT AT END DISPLAY CUST-NAME " " CUST-BAL END-READ END-PERFORM CLOSE CUST-FILE STOP RUN.
A sequential file is a stack of cards. OPEN INPUT lets you look at the next card, then the next, until the stack is empty. OPEN OUTPUT throws the stack away and you write new cards from the top. OPEN EXTEND keeps the stack and you add a card at the bottom. REWRITE means you looked at a card, changed what was written on it, and put that same card back in the same place.
Write the FILE-CONTROL entry for a sequential customer file. The program name is CUST-FILE, the DD name is CUSTFILE, access is sequential, and the status field is CUST-STAT.
The entry is SELECT CUST-FILE ASSIGN TO CUSTFILE, then ORGANIZATION IS SEQUENTIAL, ACCESS MODE IS SEQUENTIAL, and FILE STATUS IS CUST-STAT.
Open a log file so the old lines stay, write one record, and decide what status 35 means.
Use OPEN EXTEND. Status 35 means the file was not found. Add OPTIONAL to the SELECT if a missing log should be created, and expect status 05 on that open.
You have read a customer record and you need to store a new balance in that same record. Which OPEN mode do you use, and which statement stores it?
OPEN I-O, then REWRITE after the READ. OPEN OUTPUT would wipe the file. OPEN EXTEND would add a second record and leave the old balance where it was.
1. Which OPEN mode allows both reading and writing to an existing file?
2. What happens when you open a file with OUTPUT mode that already exists?
3. What is the purpose of the AT END clause in a READ statement?
4. What is the correct sequence of operations for processing a sequential file?
5. What is the purpose of checking the file status after file operations?
6. On a sequential file, what does READ NEXT do?
7. Which OPEN mode adds records after the last record already in the file?
Understanding different file organizations in COBOL.
Learn about describing file structures in the DATA DIVISION.
Working with indexed files for random access.
Handling errors and exceptions in COBOL.
Comprehensive approach to file errors.