Неявное закрытие файла
Я написал следующую программу на языке COBOL:
*************************************************************
* VERKOOP
*************************************************************
IDENTIFICATION DIVISION.
PROGRAM-ID. VERKOOP.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PRODUCTEN ASSIGN TO "BESTANDEN/PRODUCTEN"
ACCESS MODE IS RANDOM
ORGANIZATION IS INDEXED
RECORD KEY IS PRODUCTID
FILE STATUS IS WS-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD PRODUCTEN BLOCK CONTAINS 10 RECORDS.
01 PRODUCT.
02 PRODUCTID PIC X(6).
02 LEVERANCIERID PIC X(6).
02 AANTAL PIC 9(6).
WORKING-STORAGE SECTION.
77 FOUT PIC X.
88 PRODUCT-NIET-GEVONDEN VALUE 1.
77 WS-PRODUCTID PIC X(6).
77 WS-AANTAL PIC 9(6).
77 WS-FILE-STATUS PIC XX.
LINKAGE SECTION.
01 LS-PRODUCTID PIC X(6).
01 LS-AANTAL PIC 9(6).
PROCEDURE DIVISION.
* USING LS-PRODUCTID, LS-AANTAL.
MAIN.
PERFORM INITIALISEER
PERFORM LEES-PRODUCT-IN
PERFORM LEES-BESTAND
PERFORM SLUIT-BESTAND
STOP RUN.
INITIALISEER.
MOVE ZEROS TO PRODUCT
OPEN I-O PRODUCTEN.
* DISPLAY WS-FILE-STATUS..
LEES-PRODUCT-IN.
* MOVE LS-PRODUCTID TO WS-PRODUCTID
* MOVE LS-AANTAL TO WS-AANTAL.
DISPLAY "GEEF PRODUCTID OP: "
ACCEPT WS-PRODUCTID
DISPLAY "GEEF AANTAL OP: "
ACCEPT WS-AANTAL.
LEES-BESTAND.
* DISPLAY "LEES-BESTAND"
MOVE WS-PRODUCTID TO PRODUCTID
* DISPLAY PRODUCTID
READ PRODUCTEN INVALID KEY SET PRODUCT-NIET-GEVONDEN TO TRUE
END-READ
DISPLAY "END-READ" WS-FILE-STATUS
IF PRODUCT-NIET-GEVONDEN PERFORM FOUTJE
ELSE
MOVE WS-PRODUCTID TO PRODUCTID
SUBTRACT WS-AANTAL FROM AANTAL
PERFORM UPDATE-PRODUCT
END-IF.
UPDATE-PRODUCT.
REWRITE PRODUCT INVALID KEY PERFORM FOUTJE.
SLUIT-BESTAND.
* DISPLAY "SLUIT-BESTAND"
CLOSE PRODUCTEN.
FOUTJE.
DISPLAY "ER IS EEN FOUT OPGETREDEN"
* DISPLAY WS-FILE-STATUS
STOP RUN.
Идея состоит в том, что я нахожу продукт по его продукции в файле PRODUCTEN.dat и вычитаю сумму (aantal) на заданное число. Однако каждый раз, когда я запускаю его, я получаю следующую ошибку: ПРЕДУПРЕЖДЕНИЕ - неявное ЗАКРЫТИЕ PRODUCTEN <"BESTANDEN / PRODUCTEN">. Я на самом деле не вижу проблемы, линия WS-FILE-STATUS даже возвращает мне статус 00. Я на 100% уверен, что продукт находится в файле, поэтому я не пытаюсь вычесть несуществующий продукт или что-то еще.
ОБНОВЛЕНИЕ: я исправил это, назначив PRODUCTEN недавно объявленному файлу, поскольку последний (каким-то образом) был поврежден и вел себя непреднамеренно.
1 ответ
Чтобы получить это сообщение о неявном закрытии, вам необходимо выполнить STOP RUN перед тем, как закрыть файл.
У вас есть STOP RUN в параграфе FOUTJE до закрытия файла, поэтому используется параграф FOUTJE.
Вы используете параграф FOUTJE в ПРОИЗВОДИТЕЛЬНОСТИ, когда PRODUCT-NIET-GEVONDEN имеет значение true.
Для PRODUCT-NIET-GEVONDEN установлено значение true на НЕВЕРНОМ КЛЮЧЕ ЧИТАНИЯ.
Так что INVALID KEY - это правда.
Вы получите файл статуса нуля. Неожиданно, но соответствует тому, что вы представили.
У меня нет COBOL-IT, и я не знаю, какую ОС вы используете.
Я также не знаю в вашей настройке, что делает READ файла с ключом, который явно не ссылается на ключ.
Я не знаю ни в какой настройке, потому что я не делаю этого. Если я выполняю чтение по ключу, я всегда указываю ключ.
Я не помещаю данные в ключ в файле. Я использую поле WORKING-STORAGE для ключа.
Да, конечно, это зависит от реализации для компилятора, но если ваш файл ОТКРЫТ и если в нем нет текущей записи, то содержимое, даже адрес, записи файла / может (зависит от реализации) быть неопределенным.
Насколько мне известно, ключом SELECT является определение наличия ключа в файле. Ключ, который вы используете для чтения файла, очевидно, откуда-то еще.
Итак, я бы удалил это:
MOVE ZEROS TO PRODUCT
MOVE WS-PRODUCTID TO PRODUCTID
Я бы изменил это, чтобы включить ключ от WS-PRODUCTID
READ PRODUCTEN INVALID KEY SET PRODUCT-NIET-GEVONDEN TO TRUE
Я бы не использовал INVALID KEY, я бы просто использовал значение WS-FILE-STATUS, которое я бы ожидал равным "23" для "not found". Я бы сделал тест с 88-м. Вам все равно не нужен ваш "флаг" (FOUT и PRODUCT-NIET-GEVONDEN). Проверяйте поле FILE STATUS после каждого ввода-вывода. На этот раз вы правильно написали имя файла, в другой раз - нет, и вы можете тратить больше времени на преследование своего хвоста.
Работайте над последовательными отступами, это облегчит чтение вашей программы для вас и всех остальных.
Если вы хотите использовать DISPLAY для проверки логического пути, вам нужно DISPLAY значение, которое используется для определения логического пути (в данном случае FOUT).
Существует два "формата" оператора READ. Один для последовательного чтения, другой для чтения с использованием ключа. Когда каждый сводится к своему обязательному контенту, они идентичны. Поэтому для каждого компилятора неясно, какой тип READ используется по умолчанию (если он не явный) или когда он используется по умолчанию (для каждого файла). Поэтому я всегда делаю это явно:
READ PRODUCTEN KEY IS WS-PRODUCTID
Затем я бы использовал поле FILE STATUS, чтобы определить, был ли прочитан ключ (00 в статусе) или не найден (23) или что-то еще (что-то еще).
ПРИМЕЧАНИЕ. Этот ответ как решение вашей проблемы работает только в том случае, если все соответствует описанному вами. Дополнительная информация может сделать этот Ответ недействительным в качестве Резолюции.
Ответ действительно работает как более понятный (а значит, и лучший) способ кодирования вашей программы на языке COBOL.
Оказалось, что это был подозреваемый поврежденный файл. Это могло вызвать несоответствие между INVALID KEY и FILE STATUS, но в нормальном ходе событий это не произойдет. Это единственное, что соответствует всем доказательствам, но это исключительный случай, возможно, не способный воспроизвести без абсолютно одинакового повреждения файла и сжимающий эту соломинку в общем случае того, почему данная программа не работает, вероятно, является первое прибежище негодяя.