File handling in COBOL encompasses the comprehensive set of practices and techniques used to manage file operations reliably and safely. It includes proper file lifecycle management, error handling, file status checking, data validation, and implementing robust error recovery mechanisms. Good file handling ensures data integrity, prevents data loss, handles errors gracefully, and provides reliable file operations in production mainframe environments. Understanding file handling is essential for developing robust, maintainable COBOL applications.
File handling goes beyond simply performing file operations—it includes:
Effective file handling is the foundation of reliable COBOL applications that work with external data.
Every file operation in COBOL follows a standard lifecycle that must be managed properly:
Files must be defined in the ENVIRONMENT DIVISION (FILE-CONTROL) and DATA DIVISION (FILE SECTION):
1234567891011121314151617181920212223242526ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO 'CUSTOMER.DAT' ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS CUSTOMER-FILE-STATUS. DATA DIVISION. FILE SECTION. FD CUSTOMER-FILE RECORD CONTAINS 80 CHARACTERS. 01 CUSTOMER-RECORD. 05 CUSTOMER-ID PIC 9(5). 05 CUSTOMER-NAME PIC X(30). 05 CUSTOMER-ADDRESS PIC X(35). 05 CUSTOMER-STATUS PIC X. 05 FILLER PIC X(9). WORKING-STORAGE SECTION. 01 CUSTOMER-FILE-STATUS PIC XX. 88 FILE-SUCCESS VALUE '00'. 88 END-OF-FILE VALUE '10'. 88 FILE-NOT-FOUND VALUE '35'. 88 PERMANENT-ERROR VALUE '30'.
Files must be opened before any operations can be performed. Always check the file status after opening:
123456789101112131415161718192021PROCEDURE DIVISION. MAIN-PROCESS. PERFORM OPEN-FILES IF FILE-OPEN-SUCCESS PERFORM PROCESS-FILES ELSE PERFORM HANDLE-OPEN-ERROR END-IF PERFORM CLOSE-FILES STOP RUN. OPEN-FILES. OPEN INPUT CUSTOMER-FILE IF NOT FILE-SUCCESS DISPLAY 'ERROR: Failed to open customer file' DISPLAY 'Status: ' CUSTOMER-FILE-STATUS MOVE 'N' TO FILE-OPEN-SUCCESS-FLAG ELSE DISPLAY 'Customer file opened successfully' MOVE 'Y' TO FILE-OPEN-SUCCESS-FLAG END-IF.
Perform file operations (READ, WRITE, REWRITE, DELETE) with proper status checking:
1234567891011121314PROCESS-FILES. PERFORM UNTIL END-OF-FILE READ CUSTOMER-FILE AT END SET END-OF-FILE TO TRUE NOT AT END IF FILE-SUCCESS PERFORM PROCESS-CUSTOMER-RECORD ELSE PERFORM HANDLE-READ-ERROR SET END-OF-FILE TO TRUE END-IF END-READ END-PERFORM.
Always close files, even in error conditions:
12345678CLOSE-FILES. IF FILE-OPEN-SUCCESS-FLAG = 'Y' CLOSE CUSTOMER-FILE IF NOT FILE-SUCCESS DISPLAY 'WARNING: Error closing customer file' DISPLAY 'Status: ' CUSTOMER-FILE-STATUS END-IF END-IF.
File status checking is the cornerstone of proper file handling. The FILE STATUS field contains a two-character code that indicates the result of each file operation.
| Status Code | Meaning | Typical Action |
|---|---|---|
| "00" | Successful operation | Continue processing |
| "10" | End of file reached | Stop reading, handle EOF |
| "23" | Record not found | Handle missing record |
| "30" | Permanent error | Log error, terminate or recover |
| "35" | File not found | Create file or handle missing file |
| "22" | Duplicate key (indexed files) | Handle duplicate |
| "46" | Read error | Retry or handle error |
Use 88-level condition names to make status checking more readable:
1234567891011121314151617181920212223WORKING-STORAGE SECTION. 01 CUSTOMER-FILE-STATUS PIC XX. 88 FILE-SUCCESS VALUE '00'. 88 END-OF-FILE VALUE '10'. 88 RECORD-NOT-FOUND VALUE '23'. 88 PERMANENT-ERROR VALUE '30'. 88 FILE-NOT-FOUND VALUE '35'. 88 DUPLICATE-KEY VALUE '22'. PROCEDURE DIVISION. READ CUSTOMER-FILE EVALUATE TRUE WHEN FILE-SUCCESS PERFORM PROCESS-RECORD WHEN END-OF-FILE PERFORM HANDLE-END-OF-FILE WHEN RECORD-NOT-FOUND PERFORM HANDLE-RECORD-NOT-FOUND WHEN PERMANENT-ERROR PERFORM HANDLE-PERMANENT-ERROR WHEN OTHER PERFORM HANDLE-UNKNOWN-ERROR END-EVALUATE.
Effective error handling is critical for robust file operations. Here are common strategies:
Check file status after every operation and handle errors explicitly:
1234567891011121314151617181920READ-CUSTOMER-RECORD. READ CUSTOMER-FILE IF NOT FILE-SUCCESS EVALUATE CUSTOMER-FILE-STATUS WHEN '10' DISPLAY 'End of customer file reached' MOVE 'Y' TO EOF-FLAG WHEN '23' DISPLAY 'Customer record not found' ADD 1 TO NOT-FOUND-COUNT WHEN '30' DISPLAY 'Permanent error reading customer file' PERFORM LOG-ERROR MOVE 'Y' TO ERROR-FLAG WHEN OTHER DISPLAY 'Unexpected error: ' CUSTOMER-FILE-STATUS PERFORM LOG-ERROR MOVE 'Y' TO ERROR-FLAG END-EVALUATE END-IF.
Create a centralized error handling routine:
12345678910111213141516171819202122232425262728HANDLE-FILE-ERROR. EVALUATE CUSTOMER-FILE-STATUS WHEN '00' CONTINUE WHEN '10' MOVE 'End of file' TO ERROR-MESSAGE MOVE 'I' TO ERROR-SEVERITY WHEN '23' MOVE 'Record not found' TO ERROR-MESSAGE MOVE 'W' TO ERROR-SEVERITY WHEN '30' MOVE 'Permanent file error' TO ERROR-MESSAGE MOVE 'E' TO ERROR-SEVERITY WHEN '35' MOVE 'File not found' TO ERROR-MESSAGE MOVE 'E' TO ERROR-SEVERITY WHEN OTHER STRING 'Unknown file error: ' CUSTOMER-FILE-STATUS DELIMITED BY SIZE INTO ERROR-MESSAGE MOVE 'E' TO ERROR-SEVERITY END-EVALUATE PERFORM LOG-ERROR-TO-FILE IF ERROR-SEVERITY = 'E' MOVE 'Y' TO CRITICAL-ERROR-FLAG END-IF.
Implement retry logic for errors that might be transient:
1234567891011121314READ-WITH-RETRY. MOVE 0 TO RETRY-COUNT PERFORM UNTIL FILE-SUCCESS OR RETRY-COUNT >= MAX-RETRIES READ CUSTOMER-FILE IF NOT FILE-SUCCESS ADD 1 TO RETRY-COUNT IF RETRY-COUNT < MAX-RETRIES DISPLAY 'Retry attempt: ' RETRY-COUNT PERFORM WAIT-BEFORE-RETRY ELSE PERFORM HANDLE-PERMANENT-ERROR END-IF END-IF END-PERFORM.
Understanding file opening modes is crucial for proper file handling:
| Open Mode | Allowed Operations | Typical Use |
|---|---|---|
| OPEN INPUT | READ only | Reading existing files |
| OPEN OUTPUT | WRITE only | Creating new files or overwriting existing |
| OPEN I-O | READ, REWRITE, DELETE | Updating existing files |
| OPEN EXTEND | WRITE only (append) | Adding records to existing files |
12345678910111213141516171819202122232425262728*> Reading from a file OPEN INPUT CUSTOMER-FILE IF FILE-SUCCESS PERFORM READ-CUSTOMER-RECORDS END-IF CLOSE CUSTOMER-FILE *> Creating a new file OPEN OUTPUT REPORT-FILE IF FILE-SUCCESS PERFORM WRITE-REPORT-HEADER PERFORM WRITE-REPORT-DETAILS END-IF CLOSE REPORT-FILE *> Updating existing records OPEN I-O CUSTOMER-FILE IF FILE-SUCCESS PERFORM UPDATE-CUSTOMER-RECORDS END-IF CLOSE CUSTOMER-FILE *> Appending to existing file OPEN EXTEND TRANSACTION-LOG IF FILE-SUCCESS PERFORM WRITE-TRANSACTION-RECORD END-IF CLOSE TRANSACTION-LOG
Follow these best practices for reliable file handling:
Here's a complete example demonstrating proper file handling:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205IDENTIFICATION DIVISION. PROGRAM-ID. FILE-HANDLING-EXAMPLE. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT INPUT-FILE ASSIGN TO 'INPUT.DAT' ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS INPUT-FILE-STATUS. SELECT OUTPUT-FILE ASSIGN TO 'OUTPUT.DAT' ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS OUTPUT-FILE-STATUS. SELECT ERROR-LOG-FILE ASSIGN TO 'ERRORS.LOG' ORGANIZATION IS LINE SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS ERROR-LOG-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). FD ERROR-LOG-FILE RECORD CONTAINS 132 CHARACTERS. 01 ERROR-LOG-RECORD PIC X(132). WORKING-STORAGE SECTION. 01 FILE-STATUS-FIELDS. 05 INPUT-FILE-STATUS PIC XX. 88 INPUT-SUCCESS VALUE '00'. 88 INPUT-EOF VALUE '10'. 88 INPUT-ERROR VALUE '30', '35', '46'. 05 OUTPUT-FILE-STATUS PIC XX. 88 OUTPUT-SUCCESS VALUE '00'. 88 OUTPUT-ERROR VALUE '30', '35', '46'. 05 ERROR-LOG-STATUS PIC XX. 88 ERROR-LOG-SUCCESS VALUE '00'. 01 PROCESSING-FLAGS. 05 EOF-FLAG PIC X VALUE 'N'. 88 END-OF-FILE VALUE 'Y'. 05 ERROR-FLAG PIC X VALUE 'N'. 88 CRITICAL-ERROR VALUE 'Y'. 05 FILES-OPENED PIC X VALUE 'N'. 88 FILES-ARE-OPEN VALUE 'Y'. 01 COUNTERS. 05 RECORDS-READ PIC 9(7) VALUE ZERO. 05 RECORDS-WRITTEN PIC 9(7) VALUE ZERO. 05 ERROR-COUNT PIC 9(5) VALUE ZERO. 01 ERROR-MESSAGE PIC X(100). PROCEDURE DIVISION. MAIN-PROCESS. DISPLAY 'Starting file handling example...' PERFORM INITIALIZE-PROGRAM PERFORM OPEN-FILES IF FILES-ARE-OPEN AND NOT CRITICAL-ERROR PERFORM PROCESS-FILES END-IF PERFORM CLOSE-FILES PERFORM DISPLAY-STATISTICS STOP RUN. INITIALIZE-PROGRAM. MOVE ZERO TO RECORDS-READ MOVE ZERO TO RECORDS-WRITTEN MOVE ZERO TO ERROR-COUNT MOVE 'N' TO EOF-FLAG MOVE 'N' TO ERROR-FLAG MOVE 'N' TO FILES-OPENED. OPEN-FILES. DISPLAY 'Opening files...' OPEN INPUT INPUT-FILE IF NOT INPUT-SUCCESS PERFORM LOG-ERROR STRING 'Failed to open input file. Status: ' INPUT-FILE-STATUS DELIMITED BY SIZE INTO ERROR-MESSAGE DISPLAY ERROR-MESSAGE MOVE 'Y' TO ERROR-FLAG ELSE DISPLAY 'Input file opened successfully' OPEN OUTPUT OUTPUT-FILE IF NOT OUTPUT-SUCCESS PERFORM LOG-ERROR STRING 'Failed to open output file. Status: ' OUTPUT-FILE-STATUS DELIMITED BY SIZE INTO ERROR-MESSAGE DISPLAY ERROR-MESSAGE CLOSE INPUT-FILE MOVE 'Y' TO ERROR-FLAG ELSE DISPLAY 'Output file opened successfully' OPEN OUTPUT ERROR-LOG-FILE IF NOT ERROR-LOG-SUCCESS DISPLAY 'Warning: Could not open error log' ELSE DISPLAY 'Error log opened successfully' END-IF MOVE 'Y' TO FILES-OPENED END-IF END-IF. PROCESS-FILES. DISPLAY 'Processing files...' PERFORM UNTIL END-OF-FILE OR CRITICAL-ERROR READ INPUT-FILE AT END SET END-OF-FILE TO TRUE NOT AT END IF INPUT-SUCCESS ADD 1 TO RECORDS-READ PERFORM PROCESS-RECORD ELSE PERFORM HANDLE-READ-ERROR END-IF END-READ END-PERFORM. PROCESS-RECORD. *> Validate and process the record IF INPUT-RECORD NOT = SPACES MOVE INPUT-RECORD TO OUTPUT-RECORD WRITE OUTPUT-RECORD IF OUTPUT-SUCCESS ADD 1 TO RECORDS-WRITTEN ELSE PERFORM HANDLE-WRITE-ERROR END-IF END-IF. HANDLE-READ-ERROR. ADD 1 TO ERROR-COUNT STRING 'Error reading input file. Status: ' INPUT-FILE-STATUS DELIMITED BY SIZE INTO ERROR-MESSAGE DISPLAY ERROR-MESSAGE PERFORM LOG-ERROR IF INPUT-ERROR MOVE 'Y' TO ERROR-FLAG END-IF. HANDLE-WRITE-ERROR. ADD 1 TO ERROR-COUNT STRING 'Error writing output file. Status: ' OUTPUT-FILE-STATUS DELIMITED BY SIZE INTO ERROR-MESSAGE DISPLAY ERROR-MESSAGE PERFORM LOG-ERROR IF OUTPUT-ERROR MOVE 'Y' TO ERROR-FLAG END-IF. LOG-ERROR. IF ERROR-LOG-SUCCESS STRING FUNCTION CURRENT-DATE ' - ' ERROR-MESSAGE DELIMITED BY SIZE INTO ERROR-LOG-RECORD WRITE ERROR-LOG-RECORD END-IF. CLOSE-FILES. DISPLAY 'Closing files...' IF FILES-ARE-OPEN CLOSE INPUT-FILE IF NOT INPUT-SUCCESS DISPLAY 'Warning: Error closing input file' END-IF CLOSE OUTPUT-FILE IF NOT OUTPUT-SUCCESS DISPLAY 'Warning: Error closing output file' END-IF IF ERROR-LOG-SUCCESS CLOSE ERROR-LOG-FILE END-IF MOVE 'N' TO FILES-OPENED END-IF. DISPLAY-STATISTICS. DISPLAY 'Processing complete.' DISPLAY 'Records read: ' RECORDS-READ DISPLAY 'Records written: ' RECORDS-WRITTEN DISPLAY 'Errors encountered: ' ERROR-COUNT.
Avoid these common mistakes:
Think of file handling like taking care of a library book:
Just like you'd check if a book page is torn before reading it, you check file status before using file data. And just like you always return books to the library, you always close files when you're done!
Complete these exercises to reinforce your understanding:
Create a program that opens an input file, reads all records, validates each record, and writes valid records to an output file. Include proper error handling and file status checking.
Enhance the program from Exercise 1 to log all errors (file errors and validation errors) to an error log file with timestamps.
Create a file reading routine that implements retry logic for transient errors, attempting up to 3 times before giving up.
Create a program that opens multiple files (input, output, error log), processes data from input to output, logs errors, and ensures all files are properly closed even if errors occur.
Create a centralized file status handler that uses EVALUATE to handle all possible file status codes and provides appropriate error messages and recovery actions.
1. What should you do after every file operation in COBOL?
2. What is the file status code for a successful operation?
3. When should you close a file in COBOL?
4. What is the purpose of using 88-level condition names for file status?
5. What happens if you try to write to a file opened for INPUT?
6. What is the recommended approach for handling multiple file operations?