FILE Handling in COBOL

File Handling
===============

This section outlines how data can read from and written to files, how
records are organized within a file and how records can be manipulated
(e.g. sorting, merging).


1)Reading and Writing
-----------------------------
In order to either read, alter or create a new file, we must first
open it (even if it doesn't even exist yet). In doing so, a open mode
must be defined.

To simply read data from an existing file it would be opened in INPUT
mode. In this mode, the file is read-only and cannot be altered in any
way.
If writing to new file, i.e. creating one (or overwriting an existing
file so be careful) the new file would be opened in OUTPUT mode. You
cannot read data from a file opened in OUTPUT mode.
EXTEND mode allows for records to be added to the end of an existing file.
I-O mode is for input and output access to the file, such as when you
wish to update a record, or delete a record.

When a file is no longer required, the file needs to be closed again
(using CLOSE). You can open and close a file as often as you like
during a program run, although bear in mind that each time you open a
file the computer will read from the first record onwards (in INPUT
and I-O mode) or will overwrite in OUTPUT mode.

OPEN {INPUT or OUTPUT or I-O or EXTEND} {filename-1}...
{INPUT or OUTPUT or I-O or EXTEND} {filename-2}...


e.g.


OPEN INPUT DATA-1-FILE DATA-2-FILE
OUTPUT NEW-DATA-FILE

CLOSE DATA-1-FILE DATA-2-FILE NEW-DATA-FILE

READ
=============
The READ statement will read the data from a file, taking precisely
the data that is defined in the file descriptor (FD) in the data
division (file section) (see The Four Divisions section).
The format is:


READ {FD filename}
AT END {statements}
NOT AT END {statements}
END-READ

Since a file would likely contain more than one record, the READ
statement is often contained within a PERFORM loop:


IDENTIFICATION DIVISION.
PROGRAM-ID. READ-EXAMPLE.
AUTHOR ZINGMATTER.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
ASSIGN IN-FILE TO 'A:CUSTOMER.DAT'
ORGANIZATION IS LINE SEQUENTIAL.
ASSIGN PRINT-FILE TO PRINTER.
DATA DIVISION.
FILE SECTION.
FD IN-FILE.
01 CUSTOMER-DETAILS.
03 CUS-NAME PIC X(20).
03 CUS-NUM PIC 9(6).

FD PRINT-FILE.
01 PRINT-REC PIC X(60).

WORKING-STORAGE SECTION.
01 EOF-FLAG PIC X.
88 END-OF-IN-FILE VALUE 'Y'.
01 P-CUS-DETAILS
03 PIC X(5) VALUE SPACES.
03 P-NAME PIC X(25).
03 P-NUM PIC Z(5)9.

PROCEDURE DIVISION.
MAIN-PARAGRAPH.
OPEN INPUT IN-FILE
***********************"Prime" read
READ IN-FILE
AT END MOVE 'Y' TO EOF-FLAG
NOT AT END PERFORM PRINT-DETAILS
END-READ
***********Main reading loop
PERFORM UNTIL END-OF-IN-FILE
READ IN-FILE
AT END MOVE 'Y' TO EOF-FLAG
NOT AT END PERFORM PRINT-DETAILS
END-READ
END-PERFORM
STOP RUN.

PRINT-DETAILS.
MOVE CUS-NAME TO P-NAME
MOVE CUS-NUM TO P-NUM
WRITE PRINT-REC FROM P-CUS-DETAILS AFTER 1 LINE.


* A record containing a customer name (CUS-NAME) and the customer
number (CUS-NUM) are read from a file customer.dat assign to IN-FILE.

* The file is opened for INPUT (i.e. read-only).

* The "prime read" refered to in the comment is the initial read of
IN-FILE that allows for the possibility that the file contains no
records.

* The AT END clause tests for the end of file condition. When true, a
series of statements can then be executed. Likewise, the NOT AT END
clause allows for a series of statements to be executed when this
condition is true. In the above example, when the file contains no
more records (i.e. is at the end of the file) 'Y' is moved to
EOF-FLAG, thereby making the condition name condition (END-OF-IN-FILE)
true. When not at the end of the file, a record is read into memory
and the paragraph PRINT-DETAILS is executed.

* The statements between PERFORM UNTIL... and END-PERFORM are executed
until the END-OF-IN-FILE condition is true (when the AT END of the
read statement is true).

If you want to place data from a record into an item in
WORKING-STORAGE (in addition to the memory space already allocated to
the same data defined in the data division - so not much call for it),
then use READ ... INTO. i.e:


READ IN-FILE INTO W-RECORD-IN


2) REWRITE, DELETE, and EXTEND
==============================

In order to ammend a record in a file, such as to update data (see
League Table Program in sample programs section), to delete a record
altogther, or to add a record to the end of a file, you can use
REWRITE, DELETE or EXTEND, respectively.

However, to use REWRITE or DELETE you must open the file using I-O
mode. Also, DELETE can only be used on files with RELATIVE or INDEXED
organization (see example below).

RELATIVE and INDEXED files are discussed in the following section

The format of the DELETE statement is:

DELETE filename
ON INVALID KEY
{statements}
NOT ON INVALID KEY
{statements}

END-DELETE


ON INVALID KEY means the record was not found, so you might want to
display an error message

e.g. DISPLAY 'RECORD NOT FOUND'

To REWRITE you can refer to the level 01 name to change the record
with the ammended field:

FD IN-FILE
01 RECORD-IN.
03 IN-NAME PIC X(20).
03 IN-ADDRESS PIC X(60).

PROCEDURE DIVISION.
MAIN-PARAGRAPH.
:

OPEN I-O IN-FILE
:

READ IN-FILE

IF IN-NAME = 'BILLY NOMATES' THEN
MOVE 'JIMMY MOREPALS' TO IN-NAME
REWRITE RECORD-IN
ELSE
DISPLAY IN-NAME
END-IF
:

To EXTEND you must open the file in EXTEND mode:

OPEN EXTEND IN-FILE
:

DISPLAY 'Type in new name'
ACCEPT NEW-NAME
MOVE NEW-NAME TO IN-NAME
EXTEND IN-FILE

DISPLAY 'Type in new address'
ACCEPT NEW-ADDRESS
MOVE NEW-ADDRESS TO IN-ADDRESS
EXTEND IN-FILE
:

Here is a sample program that deletes a record from an INDEXED file
using the DELETE statement, followed by deletion of a record that does
not use the DELETE statement but writes the whole file (less the
record to be deleted) to a temporary file. The program asks for a six
digit code that identifies the record to be removed from the file. If
you want to try this program then you'll need to create a couple of
test files: TESTDATA1.DAT and TESTDATA2.TXT.

TESTDATA1.DAT needs to be an indexed file. To create this you'll need
to compile and run the Create INDEXED file program and Read INDEXED
file program (both in the Sample Code section).

TESTDATA2.TXT should be LINE SEQUENTIAL and of the form:

CODE--SOME ENTRY OF 43 CHARACTERS
123456abc----------**********----------**********
:
:


Sample program :-
-------------------
IDENTIFICATION DIVISION.
PROGRAM-ID. DELETION-EXAMPLE.
AUTHOR. TIM-R-P-BROWN.
* Program that deletes a record from a
000050* file where the specified record ID code is entered
000060* by the user. 2 differing methods are used.
000070
000080 ENVIRONMENT DIVISION.
000090
000100 INPUT-OUTPUT SECTION.
000110 FILE-CONTROL.
000120 000130 SELECT IN-FILE-1 ASSIGN TO 'TESTDATA1.DAT'
000140 ORGANIZATION IS INDEXED
000150 ACCESS MODE IS DYNAMIC
000160 RECORD KEY IS RECORD-CODE-1.
000170 SELECT IN-FILE-2 ASSIGN TO 'TESTDATA2.TXT'
000180 ORGANIZATION IS LINE SEQUENTIAL.
000190 SELECT TEMP-FILE ASSIGN TO 'TEMP.TXT'
000200 ORGANIZATION IS LINE SEQUENTIAL.
000210 000220 DATA DIVISION.
000230 FILE SECTION.
000240 000250 FD IN-FILE-1.
000260 01 RECORD-1.
000270 03 RECORD-CODE-1 PIC X(6).
000280 03 RECORD-DETAILS-1 PIC X(43).
000290 000300 FD IN-FILE-2.
000310 01 RECORD-2.
000320 03 RECORD-CODE-2 PIC X(6).
000330 03 RECORD-DETAILS-2 PIC X(43).
000340 000350 FD TEMP-FILE.
000360 01 TEMP-RECORD.
000370 03 TEMP-CODE PIC X(6).
000380 03 TEMP-DETAILS PIC X(43).
000390 000400
000410 000420 WORKING-STORAGE SECTION.
000430 000440 01 END-OF-FILE-FLAG PIC X VALUE 'N'.
000450 88 EOF VALUE 'Y'.
000460 000470 01 REC-DELETE-FLAG PIC X VALUE 'N'.
000480 88 RECORD-DELETED VALUE 'Y'.
000490
000500 01 DEL-CODE PIC X(6) VALUE SPACES.
000510 000520
000530
000540 PROCEDURE DIVISION.
000550 000560 MAIN-PARAGRAPH.
000570 000580 PERFORM FIRST-METHOD
000590 MOVE 'Y' TO END-OF-FILE-FLAG
000600 PERFORM SECOND-METHOD
000610 STOP RUN.
000620 000630***********************************************************
000640 000650 FIRST-METHOD.
000660* Paragraph that uses the DELETE to remove a record
000670 000680 DISPLAY 'Enter 6 digit code of record to be deleted'
000690 ACCEPT RECORD-CODE-1
000700 OPEN I-O IN-FILE-1
000710 000720 000730 DELETE IN-FILE-1
000740 INVALID KEY DISPLAY 'RECORD NOT FOUND'
000750
000760 END-DELETE
000770
000780
000790 CLOSE IN-FILE-1.
000800 000810***********************************************************
000820 000830 SECOND-METHOD.
000840* Paragraph that writes to a temporary file without
000850* including the record to be deleted
000860 000870 DISPLAY 'Enter 6 digit code of record to be deleted'
000880 ACCEPT DEL-CODE
000890 OPEN INPUT IN-FILE-2
000900 OUTPUT TEMP-FILE
000910 000920 MOVE 'N' TO REC-DELETE-FLAG
000930 MOVE 'N' TO END-OF-FILE-FLAG
000940 000950*----first write all records (except the selected one) to
000960*----the temporary file
000970 PERFORM UNTIL EOF
000980 READ IN-FILE-2
000990 AT END SET EOF TO TRUE
001000 NOT AT END
001010 IF RECORD-CODE-2 = DEL-CODE THEN
001020 SET RECORD-DELETED TO TRUE
001030 ELSE
001040 WRITE TEMP-RECORD FROM RECORD-2
001050 END-IF
001060 END-READ
001070 END-PERFORM
001080 001090 001100 001110 IF NOT RECORD-DELETED THEN
001120 DISPLAY 'Record not found'
001130 END-IF
001140 001150 CLOSE IN-FILE-2 TEMP-FILE
001160 001170 MOVE 'N' TO END-OF-FILE-FLAG
001180 001190*----now read all records from temp-file to a new 'TESTDATA-2.TXT'
001200*----This is virtually the same as just renaming the temporary file
001210*----when you think about it, just done the COBOL way!
001220 OPEN INPUT TEMP-FILE
001230 OUTPUT IN-FILE-2
001240*---------the original 'TESTDATA-2.TXT' will be overwritten-----*
001250 001260 PERFORM UNTIL EOF
001270 READ TEMP-FILE
001280 AT END SET EOF TO TRUE
001290 NOT AT END
001300 WRITE RECORD-2 FROM TEMP-RECORD
001310 END-READ
001320 END-PERFORM
001330 001340 CLOSE TEMP-FILE IN-FILE-2.
001350 001360***********************************************************
001370***********************************************************

No comments:

Post a Comment