JRecord - файл форматирования, переданный из мэйнфрейма

Я пытаюсь отобразить файл мэйнфрейма в приложении RCP eclipse, используя библиотеку JRecord. У меня уже есть тетрадь COBOL в виде текстового файла. чтобы достичь этого,

  1. Я передаю файл с мэйнфрейма на рабочий стол через API Apache Commons Net FTPClient
  2. Теперь у меня есть текстовый файл
  3. Я удаляю символы перевода строки и возврата каретки
  4. затем я читаю его через., CobolIoProvider и преобразовываю его в ArrayList типа AbstractLine

Но у меня есть проблемы смещения из-за некоторых специальных символов. вот вопросы

  1. когда я не выполняю шаг № 3, возникают проблемы со смещением прямо из записи 1. следовательно, я включил шаг № 3
  2. даже когда я выполняю шаг № 3, первые несколько тысяч записей кажутся отформатированными (или прочитанными) в AbstractLineReader правильно, если только он не встречает специальный символ (не уверен, но это мое предположение).

Фрагмент кода:

ArrayList<AbstractLine> lines = new ArrayList<AbstractLine>();
        InputStream copyStream;
        InputStream fis;
        try {
            copyStream = new FileInputStream(new File(copybookfile));

            String filec = FileUtils.readFileToString(new File(datafile));
            System.out.println("initial len: "+filec.length());
            filec=filec.replaceAll("\r", "");
            filec=filec.replaceAll("\n", "");
            System.out.println("initial len: "+filec.length());

            fis= new ByteArrayInputStream(filec.getBytes());

            CobolIoProvider ioProvider = CobolIoProvider.getInstance();
            AbstractLineReader reader = ioProvider.newIOBuilder(copyStream, "REQUEST",
                    Convert.FMT_MAINFRAME).newReader(fis);
            AbstractLine line;
            while ((line = reader.read()) != null) {
                lines.add(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

Что мне здесь не хватает? Есть ли дополнительная предварительная обработка, которую мне нужно сделать для файла, переданного с мэйнфрейма?

2 ответа

Решение

Если это текстовый файл (без двоичных данных) с разделителями строк \r\n, попробуйте:

    ArrayList<AbstractLine> lines = new ArrayList<AbstractLine>();
    InputStream copyStream;
    InputStream fis;
    try {
        copyStream = new FileInputStream(new File(copybookfile));

        AbstractLineReader reader = CobolIoProvider.getInstance() 
            .newIOBuilder(copyStream, "REQUEST", ICopybookDialects.FMT_MAINFRAME)
                .setFileOrganization(Constants.IO_STANDARD_TEXT_FILE)
            .newReader(datafile);
        AbstractLine line;
        while ((line = reader.read()) != null) {
            lines.add(line);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

Примечание: setFileOrganization сообщает JRecord, какой это тип файла. Поэтому .setFileOrganization(Constants.IO_STANDARD_TEXT_FILE) сообщает JRecord, что это текстовый файл с маркерами конца строки \ n или \r\n. Вот описание организации файла в JRecord.

Однако меня беспокоит специальный символ, если в "Data" есть \ n, он будет рассматриваться как конец строки. Возможно, вам потребуется выполнить двоичную передачу и сохранить RDW (Record-Descriptor-Word), если это файл VB.

Если файл содержит двоичные данные, вам потребуется:

  • сделать двоичную передачу (с RDW, если это файл VB)
  • используйте соответствующую File-Organization
  • Укажите Ebcdic (.setFont ("cp037") говорит, что JRecord является US-Ebcdic)

Я добавлю второй ответ для генерации кода с использованием RecordEditor


Если вы абсолютно уверены, что все записи имеют одинаковую длину, вы можете использовать низкоуровневые процедуры для чтения, см. Программу ReadAqtrans.java по https://sourceforge.net/p/jrecord/discussion/678634/thread/4b00fed4/

в основном вы бы сделали:

    ICobolIOBuilder iobuilder = CobolIoProvider.getInstance()
            .newIOBuilder("copybookFileName", ICopybookDialects.FMT_MAINFRAME)
                    .setFont("CP037")
                    .setFileOrganization(Constants.IO_FIXED_LENGTH);
    LayoutDetail layout = iobuilder.getLayout();
    FixedLengthByteReader br 
         = new FixedLengthByteReader(layout.getMaximumRecordLength() + 2);
    br.open("...");

    byte[] bytes;
    while ((bytes = br.read()) != null) {           
        lines.add(iobuilder.newLine(bytes));
    }

Будущее Ссылка / Двоичный файл

Если файл содержит двоичные данные, вам действительно нужно выполнить двоичную передачу. Вы можете найти RecordEditor полезным.

RecordEditor 0.98 имеет функцию генерации кода JRecord. Преимущества использования функции RecordEditor Generate заключаются в

  • Recordeditor попытается определить соответствующие атрибуты файла, посмотрев на файл.
  • Вы можете попробовать различные атрибуты (левая панель) и посмотреть, как файл выглядит с этими атрибутами (правая сторона).
  • Когда все будет в порядке, нажмите кнопку "Создать", и RecordEditor сгенерирует код JRecord. Доступно несколько шаблонов кода:

    • Стандартный - сгенерирует базовый код JRecord (с классом имени поля
    • lineWrapper - сгенерирует класс-оболочку с полями Cobol, представленными как методы get / set

RecordEditor Generate

В RecordEditor выберите " Создать"> "Код Java~JRecord для Cobol".

введите описание изображения здесь

Создать экран

Войдите в Cobol CopyBook / Sample file и настройте атрибуты по мере необходимости

введите описание изображения здесь

Шаблон кода

Далее вы можете выбрать шаблон кода

введите описание изображения здесь

Сгенерированный код

Наконец RecordEditor сгенерирует код JRecord на основе введенных атрибутов.

введите описание изображения здесь

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