[COBOLのはじめ方] Part14: ファイルのOPEN/CLOSE/READ/WRITE操作

ファイル操作はCOBOLプログラミングの基本!このステップでは、ファイルの基本的な読み書き操作を学びます。

COBOLは、特に業務アプリケーションで大量のデータを扱うために広く使われてきました。その中心となるのがファイル処理です。顧客情報、取引データ、在庫情報など、多くのデータはファイルとして保存され、プログラムによって読み書きされます。

このセクションでは、ファイルを操作するための基本的な命令である OPEN, CLOSE, READ, WRITE の使い方を学びます。これらの命令は、特に順編成ファイル(シーケンシャルファイル)の処理で基本となります。しっかりマスターしましょう!

目的

プログラムでファイルを読み書きする前に、そのファイルを使用可能な状態にする必要があります。これが OPEN 文の役割です。ファイルとプログラムの間の接続を確立します。

基本的な構文

OPEN iomode file-name 
  • iomode: ファイルをどのように開くかを指定します(モード)。
  • file-name: ENVIRONMENT DIVISION の SELECT句で定義したファイル名を指定します。

オープンモード (iomode)

OPEN 文では、ファイルの用途に応じてモードを指定します。主なモードは以下の通りです。

モード説明主な用途
INPUT入力モード。既存のファイルからデータを読み込むために開きます。READ
OUTPUT出力モード。新しいファイルを作成してデータを書き込むか、既存のファイルを上書きするために開きます。WRITE
I-O入出力モード。既存のファイルを読み書き(更新)するために開きます。(順編成ファイルでは通常あまり使われませんが、相対ファイルや索引ファイルで使われます)READ, WRITE, REWRITE
EXTEND追加モード。既存のファイルの末尾にデータを追加するために開きます。(順編成ファイルでよく使われます)WRITE
ポイント: どのモードでファイルを開くかによって、そのファイルに対して実行できる操作(READ, WRITEなど)が決まります。

使用例

* 入力ファイルを開く
OPEN INPUT input-file.
* 出力ファイルを開く
OPEN OUTPUT output-file.
* 複数のファイルを同時に開くことも可能
OPEN INPUT file-a OUTPUT file-b EXTEND file-c. 

ファイルを操作する前には、必ず対応するモードで OPEN する必要があります。

目的

INPUT または I-O モードで開かれたファイルから、レコード(データの1行または1単位)を読み込みます。順編成ファイルの場合、ファイルポインタ(現在位置)にある次のレコードを読み込みます。

基本的な構文 (順編成ファイル)

READ file-name [ INTO data-item ] [ AT END statement-1 ] [ NOT AT END statement-2 ]
END-READ. 
  • file-name: 読み込むファイル名(SELECT句で定義)。
  • INTO data-item (オプション): 読み込んだレコードを、DATA DIVISIONのFILE SECTIONで定義したレコード領域だけでなく、WORKING-STORAGE SECTIONなどで定義した data-item にも格納します。MOVE文と同じ動きをします。
  • AT END statement-1: ファイルの終端に達し、読み込むレコードがなくなった場合に statement-1 を実行します。ファイルの終わりを検出するために非常に重要です。
  • NOT AT END statement-2 (オプション): レコードの読み込みが成功した場合に statement-2 を実行します。
  • END-READ (オプション): READ文の範囲を明示的に示す終端符号です。
注意: READ 文を実行する前に、ファイルは INPUT または I-O モードで OPEN されている必要があります。

使用例 (ファイルの終わりまで繰り返し読み込む)

* ファイルの終わりを示すフラグ (WORKING-STORAGE SECTIONで定義)
* 01 WS-FILE-STATUS PIC X VALUE '0'.
* 88 END-OF-FILE VALUE '1'.
PROCEDURE DIVISION. OPEN INPUT input-file. * 最初のREAD READ input-file AT END SET END-OF-FILE TO TRUE END-READ. * ファイルの終わりまでループ PERFORM UNTIL END-OF-FILE * --- 読み込んだレコードに対する処理 --- DISPLAY "読み込んだデータ: " input-record * 次のレコードを読み込む READ input-file AT END SET END-OF-FILE TO TRUE END-READ END-PERFORM. CLOSE input-file. 

この例では、PERFORM UNTILAT END 句を組み合わせて、ファイルの全レコードを処理しています。最初の READ (初期読み込み) をループの前に行い、ループ内では処理の後に次の READ を行うのが一般的なパターンです。

目的

OUTPUT, I-O, EXTEND のいずれかのモードで開かれたファイルに、新しいレコードを書き込みます。

基本的な構文 (順編成ファイル)

WRITE record-name [ FROM data-item ] [ { BEFORE | AFTER } ADVANCING { integer | identifier } [ LINE | LINES ] ]
END-WRITE. 
  • record-name: 書き込むレコード名(FILE SECTIONのFD句で定義された01レベル項目)。
  • FROM data-item (オプション): WORKING-STORAGE SECTIONなどで定義された data-item の内容を record-name にMOVEしてから書き込みます。
  • ADVANCING句 (オプション): 主に帳票出力(プリンタファイル)で使用され、書き込み前(BEFORE)または後(AFTER)に指定した行数だけ改行します。PAGEを指定すると改ページします。通常のデータファイルではあまり使いません。
  • END-WRITE (オプション): WRITE文の範囲を明示的に示す終端符号です。
注意: WRITE 文を実行する前に、ファイルは適切なモード (OUTPUT, I-O, EXTEND) で OPEN されている必要があります。また、WRITE 文で指定する record-name には、書き込みたいデータが事前に設定されている必要があります(FROM 句を使わない場合)。

使用例 (データを準備して書き込む)

* WORKING-STORAGE SECTION に作業領域を定義
* 01 WS-OUTPUT-DATA.
* 05 WS-USER-ID PIC X(10).
* 05 WS-USER-NAME PIC X(20).
* FILE SECTION に出力レコードを定義
* FD output-file.
* 01 output-record.
* 05 OUT-ID PIC X(10).
* 05 OUT-NAME PIC X(20).
PROCEDURE DIVISION. OPEN OUTPUT output-file. * 書き込むデータを準備 MOVE "USER001" TO WS-USER-ID. MOVE "Taro Yamada" TO WS-USER-NAME. * 方法1: FROM句を使う WRITE output-record FROM WS-OUTPUT-DATA. * 方法2: レコード領域に直接MOVEしてからWRITE MOVE "USER002" TO OUT-ID. MOVE "Hanako Suzuki" TO OUT-NAME. WRITE output-record. CLOSE output-file. 

WRITE 文を実行すると、record-name の内容がファイルに書き込まれます。一度書き込むと、record-name の内容は保証されなくなる(不定になる)ことがあるため、FROM 句を使うか、書き込む直前にデータを MOVE するのが一般的です。

目的

OPEN していたファイルとプログラムの接続を解除し、ファイル処理を終了します。ファイルバッファに残っているデータがあれば、それをディスクに書き出すなどの後処理も行われます。

基本的な構文

CLOSE file-name [ file-name ] ... 
  • file-name: 閉じるファイル名を指定します。複数のファイルを一度に指定することも可能です。
重要: ファイルの処理が終わったら、必ず CLOSE 文でファイルを閉じるようにしましょう。ファイルを閉じることで、データの損失を防ぎ、他のプログラムがそのファイルを利用できるようになります。プログラムが正常終了すれば自動的に閉じられることもありますが、明示的に CLOSE するのが良い習慣です。

使用例

PROCEDURE DIVISION. OPEN INPUT input-file OUTPUT output-file. * ... ファイル処理 ... * ファイルを閉じる CLOSE input-file output-file. STOP RUN. 

これまでに学んだ OPEN, READ, WRITE, CLOSE を使って、入力ファイルの内容を出力ファイルにコピーする簡単なプログラムを見てみましょう。

IDENTIFICATION DIVISION.
PROGRAM-ID. FILECOPY.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL. SELECT INPUT-FILE ASSIGN TO "input.dat" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-IN-STATUS. SELECT OUTPUT-FILE ASSIGN TO "output.dat" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-OUT-STATUS.
DATA DIVISION.
FILE SECTION.
FD INPUT-FILE.
01 INPUT-RECORD PIC X(80).
FD OUTPUT-FILE.
01 OUTPUT-RECORD PIC X(80).
WORKING-STORAGE SECTION.
01 WS-STATUS. 05 WS-IN-STATUS PIC XX. 05 WS-OUT-STATUS PIC XX.
01 WS-EOF-FLAG PIC X VALUE '0'. 88 IS-EOF VALUE '1'.
PROCEDURE DIVISION.
MAIN-PROCEDURE. PERFORM OPEN-FILES. PERFORM PROCESS-RECORDS UNTIL IS-EOF. PERFORM CLOSE-FILES. STOP RUN.
OPEN-FILES. OPEN INPUT INPUT-FILE OUTPUT OUTPUT-FILE. * OPENエラーチェック (簡易版) IF WS-IN-STATUS NOT = "00" DISPLAY "ERROR OPENING INPUT FILE: " WS-IN-STATUS STOP RUN END-IF. IF WS-OUT-STATUS NOT = "00" DISPLAY "ERROR OPENING OUTPUT FILE: " WS-OUT-STATUS STOP RUN END-IF. * 初期読み込み PERFORM READ-INPUT-FILE.
PROCESS-RECORDS. IF NOT IS-EOF PERFORM WRITE-OUTPUT-FILE PERFORM READ-INPUT-FILE END-IF.
READ-INPUT-FILE. READ INPUT-FILE AT END SET IS-EOF TO TRUE NOT AT END CONTINUE *> 何もしない場合は CONTINUE が使える END-READ. * READエラーチェック (簡易版) IF WS-IN-STATUS NOT = "00" AND WS-IN-STATUS NOT = "10" *> 10はEOF DISPLAY "ERROR READING INPUT FILE: " WS-IN-STATUS STOP RUN END-IF.
WRITE-OUTPUT-FILE. WRITE OUTPUT-RECORD FROM INPUT-RECORD. * WRITEエラーチェック (簡易版) IF WS-OUT-STATUS NOT = "00" DISPLAY "ERROR WRITING OUTPUT FILE: " WS-OUT-STATUS STOP RUN END-IF.
CLOSE-FILES. CLOSE INPUT-FILE OUTPUT-FILE. * CLOSEエラーチェックも本来は行うべき
END PROGRAM FILECOPY. 

今回は、COBOLにおけるファイル操作の基本である OPEN, READ, WRITE, CLOSE を学びました。

  • OPEN: ファイルを使用可能な状態にする(モード指定が重要)。
  • READ: ファイルからデータを1レコードずつ読み込む(AT ENDでの終了判定が必須)。
  • WRITE: ファイルにデータを1レコードずつ書き込む。
  • CLOSE: ファイルの後処理を行い、接続を閉じる(忘れずに!)。

これらの命令は、COBOLでデータを扱う上で欠かせないものです。特に順編成ファイルの処理は基本中の基本なので、しっかり理解しておきましょう。次のステップでは、これらの知識を活かして、データのソートなど、より実践的なファイル処理に進みます。頑張ってください!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です