JRecord - 格式化从大型机传输的文件

JRecord - Formatting file transferred from Mainframe

我正在尝试使用 JRecord 在 eclipse RCP 应用程序中显示大型机文件 library.I 已经将 COBOL copybook 作为文本文件。 要做到这一点,

  1. 我正在通过以下方式将文件从大型机传输到我的桌面 apache commons net FTPClient API
  2. 现在我有一个文本文件
  3. 我正在删除换行符和回车符 return 个字符
  4. 然后我通过 CobolIoProvider 读取它并将其转换为 AbstractLine
  5. 类型的 ArrayList

但由于某些特殊字符,我遇到了偏移问题。 这是问题

  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();
        }

我在这里错过了什么?我需要对从大型机传输的文件进行额外的预处理吗?

如果它是带有 \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 行尾标记的文本文件。这里有一个Description of FileOrganisation in JRecord.

特殊字符 令我担心的是,如果 'Data' 中有一个 \n,它将被视为一个 end-of-行。如果它是 VB 文件,您可能需要进行二进制传输并保留 RDW(记录描述符字)。

如果文件包含二进制数据,您将需要:

  • 进行二进制传输(如果是 VB 文件则使用 RDW)
  • 使用适当的文件组织
  • 指定 Ebcdic(.setFont("cp037") 告诉 JRecord 是 US-Ebcdic)

我将使用RecordEditor

生成代码添加第二个答案

如果您绝对确定所有记录的长度都相同,则可以使用低级例程进行读取,请参阅 https://sourceforge.net/p/jrecord/discussion/678634/thread/4b00fed4/

中的 ReadAqtrans.java 程序

基本上你会做:

    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 has a JRecord code Generation 功能。使用 RecordEditor Generate 函数的优点是

  • 记录编辑器将通过查看文件
  • 尝试计算出适当的文件属性
  • 您可以尝试各种属性(左侧窗格)并查看具有这些属性的文件的外观 (右侧)。
  • 高兴时,点击“生成”按钮,RecordEditor 将生成 JRecord 代码。有几个代码模板 可用:

    • Standard - 将生成基本的 JRecord 代码(字段名称 class
    • lineWrapper - 将生成一个 "wrapper" class,其中 Cobol 字段表示为 get/set 方法

记录编辑器生成

RecordEditorselect生成>>>Java~Cobol的JRecord代码

生成屏幕

进入Cobol CopyBook/Sample文件,根据需要调整属性

代码模板

接下来您可以select 代码模板

生成的代码

最后 RecordEditor 将根据输入的属性生成 JRecord 代码。