Неявное закрытие файла

Я написал следующую программу на языке 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, но в нормальном ходе событий это не произойдет. Это единственное, что соответствует всем доказательствам, но это исключительный случай, возможно, не способный воспроизвести без абсолютно одинакового повреждения файла и сжимающий эту соломинку в общем случае того, почему данная программа не работает, вероятно, является первое прибежище негодяя.

Другие вопросы по тегам