返回首页

COBOL 文件处理

COBOL 文件处理

COBOL 最初就是为商业数据处理而生,文件处理是其核心能力。本章讲解顺序文件、索引文件的操作。

目录

  1. 文件处理概述
  2. 声明文件(ENVIRONMENT DIVISION)
  3. 定义记录(DATA DIVISION)
  4. 顺序文件操作
  5. 索引文件操作
  6. 相对文件操作
  7. 完整示例:读写顺序文件
  8. 文件状态码

1. 文件处理概述

COBOL 支持三种文件组织方式:

类型 组织方式 访问方式 适用场景
顺序文件 Sequential 只能从头到尾 日志、批处理
索引文件 Indexed 按键随机访问 数据库式查询
相对文件 Relative 按记录号访问 定长记录表

文件操作流程:

1
OPEN → READ/WRITE/REWRITE/DELETE → CLOSE

2. 声明文件(ENVIRONMENT DIVISION)

在 ENVIRONMENT DIVISION 的 INPUT-OUTPUT SECTION 中声明文件:

1
2
3
4
5
6
7
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT-FILE
ASSIGN TO "input.dat"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS WS-INPUT-STATUS.

关键子句

子句 说明
SELECT 文件名 定义逻辑文件名
ASSIGN TO "路径" 关联物理文件
ORGANIZATION IS ... 文件组织方式
ACCESS MODE IS ... 访问模式(SEQUENTIAL/RANDOM/DYNAMIC)
RECORD KEY IS ... 索引文件的主键
FILE STATUS IS ... 存储操作状态码的变量

ORGANIZATION 取值

1
2
3
4
ORGANIZATION IS LINE SEQUENTIAL    *> 行顺序(文本文件,最常用)
ORGANIZATION IS SEQUENTIAL *> 记录顺序(定长)
ORGANIZATION IS INDEXED *> 索引文件
ORGANIZATION IS RELATIVE *> 相对文件

3. 定义记录(DATA DIVISION)

在 DATA DIVISION 的 FILE SECTION 中定义记录结构:

1
2
3
4
5
6
7
8
9
10
11
DATA DIVISION.
FILE SECTION.
FD INPUT-FILE.
01 INPUT-RECORD.
05 IN-ID PIC 9(5).
05 IN-NAME PIC X(20).
05 IN-AMOUNT PIC 9(7)V99.

FD OUTPUT-FILE.
01 OUTPUT-RECORD.
05 OUT-LINE PIC X(80).
  • FD(File Description):文件描述,对应 SELECT 的逻辑文件名
  • 01 记录结构:定义每条记录的字段

4. 顺序文件操作

打开文件

1
2
3
4
OPEN INPUT  INPUT-FILE.     *> 只读
OPEN OUTPUT OUTPUT-FILE. *> 只写(会清空原文件)
OPEN EXTEND OUTPUT-FILE. *> 追加
OPEN I-O DATA-FILE. *> 读写

读取记录

1
2
3
4
READ INPUT-FILE
AT END MOVE 1 TO WS-EOF
NOT AT END PERFORM PROCESS-RECORD
END-READ.

写入记录

1
2
MOVE "Hello" TO OUT-LINE.
WRITE OUTPUT-RECORD.

关闭文件

1
2
CLOSE INPUT-FILE.
CLOSE OUTPUT-FILE.

5. 索引文件操作

索引文件支持按键随机访问。

声明

1
2
3
4
5
6
7
FILE-CONTROL.
SELECT CUSTOMER-FILE
ASSIGN TO "customer.dat"
ORGANIZATION IS INDEXED
ACCESS MODE IS DYNAMIC
RECORD KEY IS CUST-ID
FILE STATUS IS WS-STATUS.

定义记录

1
2
3
4
5
FD CUSTOMER-FILE.
01 CUSTOMER-RECORD.
05 CUST-ID PIC 9(5).
05 CUST-NAME PIC X(20).
05 CUST-BALANCE PIC 9(7)V99.

随机读取

1
2
3
4
5
MOVE 1001 TO CUST-ID.
READ CUSTOMER-FILE
INVALID KEY DISPLAY "记录不存在"
NOT INVALID KEY DISPLAY CUST-NAME
END-READ.

写入/更新/删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*> 写入新记录
MOVE 1001 TO CUST-ID
MOVE "Alice" TO CUST-NAME
WRITE CUSTOMER-RECORD
INVALID KEY DISPLAY "键重复"
END-WRITE.

*> 更新记录(需先 READ 再 REWRITE)
MOVE 1001 TO CUST-ID
READ CUSTOMER-FILE
MOVE 9999.99 TO CUST-BALANCE
REWRITE CUSTOMER-RECORD
INVALID KEY DISPLAY "更新失败"
END-REWRITE.

*> 删除记录
MOVE 1001 TO CUST-ID
DELETE CUSTOMER-FILE
INVALID KEY DISPLAY "删除失败"
END-DELETE.

顺序遍历索引文件

1
2
3
4
5
6
7
8
MOVE LOW-VALUES TO CUST-ID
START CUSTOMER-FILE KEY >= CUST-ID
PERFORM UNTIL WS-EOF = 1
READ CUSTOMER-FILE NEXT
AT END MOVE 1 TO WS-EOF
NOT AT END DISPLAY CUST-ID " " CUST-NAME
END-READ
END-PERFORM.

6. 相对文件操作

相对文件用记录号(1, 2, 3…)访问:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FILE-CONTROL.
SELECT REL-FILE
ASSIGN TO "relative.dat"
ORGANIZATION IS RELATIVE
ACCESS MODE IS RANDOM
RELATIVE KEY IS WS-REC-NUM.

FD REL-FILE.
01 REL-RECORD.
05 REL-DATA PIC X(50).

PROCEDURE DIVISION.
MOVE 5 TO WS-REC-NUM
READ REL-FILE
INVALID KEY DISPLAY "记录 5 不存在"
END-READ.

7. 完整示例:读写顺序文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
IDENTIFICATION DIVISION.
PROGRAM-ID. FILE-DEMO.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FILE
ASSIGN TO "input.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS WS-IN-STATUS.
SELECT OUT-FILE
ASSIGN TO "output.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS WS-OUT-STATUS.
DATA DIVISION.
FILE SECTION.
FD IN-FILE.
01 IN-RECORD PIC X(80).
FD OUT-FILE.
01 OUT-RECORD PIC X(80).
WORKING-STORAGE SECTION.
01 WS-IN-STATUS PIC XX.
01 WS-OUT-STATUS PIC XX.
01 WS-EOF PIC 9 VALUE 0.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
OPEN INPUT IN-FILE
OPEN OUTPUT OUT-FILE
PERFORM UNTIL WS-EOF = 1
READ IN-FILE
AT END MOVE 1 TO WS-EOF
NOT AT END
MOVE IN-RECORD TO OUT-RECORD
WRITE OUT-RECORD
END-READ
END-PERFORM
CLOSE IN-FILE
CLOSE OUT-FILE
DISPLAY "文件复制完成"
STOP RUN.

编译运行:

1
2
3
4
cobc -x -o file-demo file-demo.cob
echo "Hello COBOL" > input.txt
./file-demo
cat output.txt

8. 文件状态码

FILE STATUS 变量返回两位状态码:

状态码 含义
00 操作成功
10 到达文件末尾(AT END)
22 键重复(INVALID KEY)
23 记录不存在
30 永久错误(如文件不存在)
35 打开文件时文件不存在
37 文件已打开
41 文件已打开,无法再次打开
42 文件未打开
46 读取时未打开文件

使用示例:

1
2
3
4
5
OPEN INPUT IN-FILE
IF WS-IN-STATUS NOT = "00"
DISPLAY "打开文件失败, 状态码: " WS-IN-STATUS
STOP RUN
END-IF.

上一章: 表与数组
下一章: 子程序与调用