Чтение сгенерированного файла Cobol - PullRequest
5 голосов
/ 02 февраля 2011

В настоящее время я занимаюсь написанием приложения ac #, которое будет находиться между двумя существующими приложениями.Все, что я знаю о втором приложении, - это то, что оно обрабатывает файлы, созданные первым.Первое приложение написано на Cobol.

Шаги: 1) Приложение Cobol, записывает некоторые файлы и копирует в каталог.2) Второе приложение выбирает эти файлы и обрабатывает их.

Мое приложение на C # будет находиться между 1) и 2).Пришлось бы взять файл, сгенерированный 1), прочитать его, изменить и сохранить, чтобы приложение 2) не узнало, что я там даже был.

У меня есть несколько проблем.

  • Прежде всего, если я открою файл, сгенерированный 1) в блокноте, большая его часть не читается, в то время как другие части.
  • Если я прочитал файл, измените его и сохраните,Я должен сохранить файл в той же записи, что и приложение cobol, чтобы приложение 2) не знало, что я там был.

Я пытался прочитать файл таким образом,но он все еще не читается:

Код:

        string ss = @"filename";

        using (FileStream fs = new FileStream(ss, FileMode.Open))
        {
            StreamReader sr = new StreamReader(fs);
            string gg = sr.ReadToEnd();
        }

Также, если я найду способ сделать его читаемым (используя какую-то технику кодирования), я боюсь, что когда ясохраните файл еще раз, я могу изменить его оригинальный формат.

Есть мысли?Предложения?

Ответы [ 3 ]

27 голосов
/ 02 февраля 2011

Чтобы прочитать файл, созданный на языке COBOL, вам необходимо знать:

Для начала вам понадобится макет записи (тетрадь) для файла.Формат записи COBOL будет выглядеть примерно так:

01  PATIENT-TREATMENTS.
    05  PATIENT-NAME                PIC X(30).
    05  PATIENT-SS-NUMBER           PIC 9(9).
    05  NUMBER-OF-TREATMENTS        PIC 99 COMP-3.
    05  TREATMENT-HISTORY OCCURS 0 TO 50 TIMES
           DEPENDING ON NUMBER-OF-TREATMENTS
           INDEXED BY TREATMENT-POINTER.
        10  TREATMENT-DATE.
            15  TREATMENT-DAY        PIC 99.
            15  TREATMENT-MONTH      PIC 99.
            15  TREATMENT-YEAR       PIC 9(4).
        10  TREATING-PHYSICIAN       PIC X(30).
        10  TREATMENT-CODE           PIC 99.

Вам также понадобится копия Принципов работы IBM (S / 360, S370, z / OS, неэто действительно важно для наших целей).Последняя версия доступна в IBM по адресу

Главы 8 (десятичные инструкции) и 9 (инструкции по рассмотрению и поддержке с плавающей запятой) являются интересными частями для наших целей..

Без этого вы в значительной степени потеряны.

Затем вам нужно понять типы данных COBOL. Например:

  • PIC определяет формат в алфавитном форматеполе (PIC 9 (4), например, это 4 десятичных знака, которые могут быть заполнены пробелами, если они отсутствуют). Pic 999V99 - это 5 десятичных знаков с подразумеваемой десятичной точкой. Так далее и так далее.
  • BINARY - это [обычно] двоичное целое число со знаком с фиксированной запятой. Обычные размеры: полслово (2 октета) и полное слово (4 октета).
  • COMP-1 - число с плавающей запятой одинарной точности.
  • COMP-2 - с плавающей запятой двойной точности.

Если источником данных является мэйнфрейм IBM, COMP-1 и COMP-2, скорее всего, не будут с плавающей точкой IEE: это будет формат IBM base-16 с избыточным числом 64 с плавающей точкой .Вам понадобится что-то вроде S / 370 Принципов работы , чтобы помочь вам понять это.

  • COMP-3 - это «упакованный десятичный знак» различной длины.Упакованный десятичный знак - это компактный способ представления десятичного числа.Объявление будет выглядеть примерно так: PIC S9999V99 COMP-3.Это говорит о том, что оно подписано, состоит из 6 десятичных цифр с подразумеваемой десятичной точкой.Упакованный десятичный знак представляет каждую десятичную цифру в виде полубайта октета (шестнадцатеричные значения 0-9).Старшая цифра - это верхняя часть левого октета.Нижний клочок самого правого октета представляет собой шестнадцатеричное значение AF, представляющее знак.Таким образом, в приведенном выше предложении PIC потребуется ceil( (6+1)/2 ) или 4 октета.значение -345,67, как представлено в приведенном выше предложении PIC, будет выглядеть как 0x0034567D.Фактическое значение знака может варьироваться (по умолчанию C / положительный, D / отрицательный, но A, C, E и F рассматриваются как положительные, в то время как только B и D рассматриваются как отрицательные).Опять же, см. S \ 370 Принципы работы для получения подробной информации о представлении.

Относительно COMP-3 зональная десятичная дробь.Это может быть объявлено как `PIC S9999V99 '(со знаком, 5 десятичных цифр, с подразумеваемой десятичной точкой).Десятичные цифры в EBCDIC - это шестнадцатеричные значения 0xFO - 0xF9.«Unpack» (машинная инструкция для мэйнфрейма) принимает упакованное десятичное поле и превращается в символьное поле.Процесс:

  • начинается с самого правого октета.Инвертируйте его так, чтобы отрывочный знак был сверху и поместите его в самый правый октет поля назначения.
  • Работая справа налево (источник и цель оба), удалите каждый оставшийся клевупакованное десятичное поле и поместите его в нижний клочок следующего доступного октета в месте назначения.Заполните верхний клочок шестнадцатеричным F.

  • Операция заканчивается, когда поле источника или назначения исчерпано.

  • Если поле назначенияне исчерпывается, если он заполняется нулями слева, заполняя оставшиеся октеты десятичным '0' (oxF0).

Так что наш пример значения -345.67, если хранится со значением по умолчаниюзначение знака (hex D) будет распаковано как 0xF0F0F0F3F4F5F6D7 ('0003456P', в EBDIC).

[Вот, пожалуйста.Есть викторина позже]

  1. Если приложение COBOL живет на мэйнфрейме IBM, был ли файл преобразован из его собственного EBCDIC в ASCII?Если нет, вам придется выполнить сопоставление самостоятельно (подсказка: это не обязательно так просто, как может показаться, поскольку это может быть выборочный процесс - преобразуются только поля символов (COMP-1, COMP-2, COMP-3 и BINARY исключаются, поскольку они представляют собой последовательность двоичных октетов.) Хуже того, существует несколько разновидностей представлений EBCDIC из-за различных национальных реализаций и различных цепочек печати, используемых на разных принтерах.

Ох ... еще одна вещь. Аппаратное обеспечение мэйнфреймов имеет тенденцию любить разные вещи, выровненные по границам полуслов, слов или двойных слов, поэтому формат записи может не отображаться напрямую в октеты в файле, поскольку между полями могут быть вставлены октеты заполненияподдерживать нужное выравнивание слов.

Удачи.

2 голосов
/ 03 февраля 2011

В комментариях к вашему вопросу я вижу, что вы имеете дело со «классической» структурой пакетного файла COBOL: запись заголовка, подробные записи и запись трейлера.

Это, вероятно, плохие новости, если вы несете ответственность засоздание записи трейлера!Типичная запись «трейлера» используется для идентификации конца файла и предоставляет управляющую информацию, такую ​​как количество записей, предшествующих ей, а также различные контрольные суммы и / или общие итоги для «подробных» записей.Другими словами, вам может понадобиться прочитать и суммировать весь файл, чтобы создать трейлер.Добавьте к этому возможность того, что большая часть данных в файле представлена ​​в виде упакованного десятичного числа, зонированного десятичного числа или других числовых типов данных COBOLish. Возможно, вы столкнетесь с трудностями.

Возможно, вы захотите задать вопрос, почему выдобавление записей трейлера к этим файлам.Обычно «трейлер» создается той же программой или приложением, в котором были созданы «подробные» записи.Предполагается, что трейлер служит подтверждением того, что отправляющее приложение / программа записало все данные, которые должны были.Итоговые итоги, подсчеты и т. Д. Используются принимающим приложением для проверки того, что подробные записи соответствуют предыдущим подробностям.Это должно служить еще одним подтверждением того, что отправляющее приложение не испортило данные или что оно не было повреждено на маршруте (нет, это не шутка - но, возможно, так и должно быть).Когда «человек посередине» создает трейлеры, он как бы побеждает всю цель учения (независимо от того, насколько ошибочным он мог быть с самого начала).

2 голосов
/ 03 февраля 2011
  • Было бы полезно узнать, с каким диалектом кобола вы имеете дело, потому что есть нет единого формата Cobol. Некоторые компиляторы Cobol (Micro Focus) помещают «Описание файла» в начале файлов (для Micro Focus VB / проиндексированных файлов).

  • Посмотрите на RecordEditor (http://record -editor.sourceforge.net / ). У него есть File Wizard , который может быть очень полезен для вас.

    • В мастере файлов установите файл как файл с фиксированной шириной (наиболее распространенный в Cobol). Программа позволяет вам попробовать разные длины записи. Когда вы получите правильную длину записи, текстовые поля должны выстроиться в линию.
    • Далее в мастере есть поиск по полю, в котором можно искать двоичные, Comp-3, текстовые поля.
    • Здесь есть некоторые заметки по использованию мастера RecordEditor с неизвестным файлом http://record -editor.sourceforge.net / Unkown.htm
  • Если файл не поступает с мэйнфрейма / AS400, маловероятно, что он будет использовать EBCDIC (cp037 - под кодовым обозначением US EBCDIC), любой текст наиболее вероятен в Ascii.

  • Файл, вероятно, содержит данные Packed-Decimal (Comp3) и Binary-Integer. Большинство коболов используйте Big-Endian (для целых чисел Comp) даже на Intel (оборудование с прямым порядком байтов).

  • Одна вещь, которую следует помнить с Cobol PIC s9 (6) V99 comp, хранится как двоичное целое число с x'0001 ', представляющим 0,01. Поэтому, если у вас нет определения Кобола, вы не можете сказать, является ли двоичное 1 1 0,1, 0,01 и т. Д.

...