读取顺序输入文件的模式

Pattern for reading a sequential input file

我已经看到很多在 COBOL 中读取顺序文件的示例,看起来像这样:

FD File-Record
01  Input-Record.
    88  End-Of-File       VALUE HIGH-VALUES.
    05  ...

...

    READ File-Record
        AT END SET End-Of-File TO TRUE
    END-READ

    PERFORM UNTIL End-Of-File
        PERFORM Process-Record
        READ File-Record
            AT END SET End-Of-File TO TRUE
        END-READ
    END-PERFORM

一个问题是,这样处理是不是也一样?

    PERFORM UNTIL End-Of-File
        READ File-Record
            AT END SET End-Of-File TO TRUE
            NOT AT END PERFORM Process-Record
        END-READ
    END-PERFORM

我一般没见过第二种模式,但对我来说它似乎更简洁,冗余更少。与第一个相比有问题吗?我指的不是上述主题的变体(它们可以根据您如何定义 PERFORM 进行不同的分组)但我指的是 first record pre- 的概念read 模式,在我见过的各种例子中似乎都受到青睐。

主要问题是你只调用了一次PERFORM Process-Record,所以在这方面第二个模式没有改进。

然后你在 Cobol 中工作,但担心模式的技巧。我宁愿担心使用 Cobol 而不是 higher/newer 语言。大约 25 年前,我使用 Protos 作为隐藏原始 Cobol 的层。 . .

第一个叫做"Priming Read"。使用这意味着始终有一条记录可用于处理循环。

第二个叫做...好吧,不确定它有名字。在处理循环中,必须测试记录的可用性。

几件事。使用 AT END/NOT AT END/END-READ 本身有点笨拙(意见)。有一种更清洁的方法(它更清洁的两个原因)。

在文件的 SELECT 语句中(您应该对所有文件都这样做)定义一个 FILE STATUS 字段,每个文件单独定义一个字段。

在每个 file-access 之后,测试该文件的 file-status 字段,并确保访问给出预期结果。

使用此方法,file-status 字段将在达到 end-of-file 时自动设置为 10。因此,您将 88 移动到 file-status 字段,并将 VALUE 更改为 10.

01  INPUT-FILE-STATUS                PIC XX.
    88  INPUT-FILE-OK                VALUE ZERO "10".
    88  INPUT-FILE-EOF               VALUE "10".

PERFORM                       PRIMING-READ
PERFORM UNTIL End-Of-File
    PERFORM                   Process-Record
    PERFORM                   READ-A-RECORD05 is optional file not present, 23 is record not found.
END-PERFORM

...
PRIMING-READ.
    PERFORM                   READ-A-RECORD
    IF INPUT-FILE-EOF
        [cancel with end-of-file on first read message]
    END-IF
    .

READ-A-RECORD.
    READ File-Record
    IF NOT INPUT-FILE-OK
        [code here to check file-status field and crash if bad]
    END-IF
    .

我非常赞成priming-read。 "empty" 文件可能表示存在问题。现在您可以测试(在启动阅读之后)而不必弄乱您的主要逻辑。您不必在 end-of-file 处 "get out of the loop",因为循环只会使用当前记录进入。

传统文件会包含 "headers"(和 "trailers")。 header 将包含日期、logical-file-name 等。将读取和验证 header 以了解正在处理的是正确的文件。然后你需要检查没有两个header(因为如果你不这样做,总有一天会有)。当你这样做时,你已经有了第一条数据记录。

您不想在某些 "business" 逻辑中执行所有这些操作,也不想弄乱逻辑流程。

在 input-record 上的 88 上,请注意这是跨其他 COBOL 的 non-transportable。例如,在 IBM 大型机上,除非您的输入是 variable-length 记录并且您使用 APPLY WRITE ONLY(通过可怕的编译器选项 AWO 显式或隐式)然后在文件打开之前访问 FD 下的数据,之后被关闭,或者在end-of-file之后会导致崩溃(ABEND)。