Basic File Handling: Sequential Files

COBOL Fundamentals

Chapter 8 · Basic File Handling: Sequential Files

Every real record processed so far has lived only in WORKING-STORAGE, gone the moment the program ends. Real COBOL programs exist to read and write actual files — and a sequential file is COBOL's own most basic, most common shape: records genuinely contiguous, read one after another from the front, "similarly to a linked list."

Three Places a File Touches a Program

A real COBOL file spans three separate divisions, each doing a genuinely different job:

DivisionWhat It Declares
ENVIRONMENT DIVISIONWhich real external file this program talks to (SELECT/ASSIGN)
DATA DIVISIONWhat one real record inside that file looks like (the FD and its record layout)
PROCEDURE DIVISIONThe real verbs that actually move data in and out (OPEN, READ, WRITE, CLOSE)

SELECT & FD: Declaring the File

ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CUSTOMER-FILE ASSIGN TO "CUSTFILE.DAT" ORGANIZATION IS SEQUENTIAL FILE STATUS IS WS-FILE-STATUS. DATA DIVISION. FILE SECTION. FD CUSTOMER-FILE LABEL RECORDS ARE STANDARD. 01 CUSTOMER-RECORD. 05 CUST-ID PIC 9(6). 05 CUST-NAME PIC X(30). 05 CUST-BALANCE PIC S9(7)V99.

This chapter's real CUSTOMER-RECORD deliberately mirrors Chapter 3's own WS-CUSTOMER-RECORD — a real record layout doesn't change shape just because it's now coming from a file instead of being built by hand in WORKING-STORAGE.

OPEN: Real Access Modes

ModeWhat It Genuinely Allows
INPUTReading only, from a file that already exists
OUTPUTWriting only; a real, existing file's contents are replaced entirely
I-OBoth reading and writing on the same open file (not valid for a real line-sequential file)
EXTENDWriting new records appended after whatever a real file already contains
OPEN INPUT CUSTOMER-FILE.

READ ... AT END & the Real Priming-Read Pattern

A real READ pulls the next record in, and its AT END phrase fires the moment a read genuinely goes past the last record in the file:

READ CUSTOMER-FILE AT END MOVE "Y" TO WS-EOF-FLAG END-READ.
Why a Single READ Inside a Loop's Condition Doesn't Work READ is a real statement, not an expression a loop condition can call directly. Chapter 5's own PERFORM UNTIL can't say "loop until the next READ hits end-of-file" in one step — it needs a genuine value to test. The standard real fix is the priming read: read once before the loop starts, then read again as the very last thing the loop body does, so WS-EOF-FLAG always reflects the most recent real read by the time the loop condition is checked again.
READ CUSTOMER-FILE AT END MOVE "Y" TO WS-EOF-FLAG END-READ. PERFORM UNTIL WS-EOF-FLAG = "Y" DISPLAY CUST-NAME READ CUSTOMER-FILE AT END MOVE "Y" TO WS-EOF-FLAG END-READ END-PERFORM.

WRITE: Real Records, Not Files

OPEN OUTPUT CUSTOMER-FILE. MOVE 100234 TO CUST-ID. MOVE "SMITH, JOHN" TO CUST-NAME. MOVE 500.00 TO CUST-BALANCE. WRITE CUSTOMER-RECORD.
A Genuinely Easy Mistake WRITE always names the real 01-level record — CUSTOMER-RECORD — never the file itself. Writing WRITE CUSTOMER-FILE is a genuine compile error: COBOL writes whatever record is currently sitting in that record's own storage, and the file name never appears as the object being written.

CLOSE

CLOSE CUSTOMER-FILE.

A real, plain CLOSE releases the file — every file genuinely opened in a program needs a matching close before the program ends.

FILE STATUS: Real Result Codes

I/O status codes were a real COBOL-85 addition — the same standard that added Chapter 5's EVALUATE, Chapter 7's reference modification, and inline PERFORM. A real two-character FILE STATUS field, declared in WORKING-STORAGE and named in the file's own SELECT clause, is set after every single file operation:

CodeReal Meaning
00Operation genuinely successful
10End of file reached — the real code behind every AT END trigger
23Record not found (indexed/relative files)
35OPEN INPUT/I-O attempted against a file that genuinely doesn't exist
OPEN INPUT CUSTOMER-FILE. IF WS-FILE-STATUS NOT = "00" DISPLAY "ERROR OPENING FILE: " WS-FILE-STATUS STOP RUN END-IF.

Hands-On Exercises

Exercise 1

Using this chapter's own real material, explain in your own words why COBOL needs a priming read before a PERFORM UNTIL loop rather than simply writing PERFORM UNTIL the next READ reaches end-of-file directly in the loop's own condition.

📄 View solution
Exercise 2

Using this chapter's own real material, explain in your own words what would genuinely happen if a program opened CUSTOMER-FILE with OPEN OUTPUT when the goal was actually to read the file's existing records.

📄 View solution
Exercise 3

Using this chapter's own real material, explain in your own words why WS-FILE-STATUS being "00" after a READ statement genuinely can't be relied on forever within a real priming-read loop, and what real status value eventually replaces it.

📄 View solution

Chapter 8 Quick Reference

  • SELECT ... ASSIGN TO (ENVIRONMENT DIVISION) — names the real external file; FD (DATA DIVISION) — describes one real record's layout
  • OPEN INPUT/OUTPUT/I-O/EXTEND — real access modes; OUTPUT genuinely replaces existing content
  • READ ... AT END — fires once a read genuinely passes the last record; needs a real priming read before a PERFORM UNTIL loop
  • WRITE — always names the real 01-level record, never the file itself
  • CLOSE — every genuinely opened file needs a matching close
  • FILE STATUS (COBOL-85) — real 2-character result code after every file operation; 00 success, 10 end of file, 35 file not found on OPEN