0

我在互联网上引用了一个代码来将 comp 3 解压缩为 java 中的数字。我试图将示例 comp3 文件传递​​给代码,但没有得到正确的解包数据。我得到了一些奇怪的数字。我是这个概念的新手(comp 3),所以你们能帮我解决这个问题。提前致谢

下面是我的代码


import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Converts between integer and an array of bytes in IBM mainframe packed
 * decimal format. The number of bytes required to store an integer is (digits +
 * 1) / 2. For example, a 7 digit number can be stored in 4 bytes. Each pair of
 * digits is packed into the two nibbles of one byte. The last nibble contains
 * the sign, 0F for positive and 0C for negative. For example 7654321 becomes
 * 0x76 0x54 0x32 0x1F.
 * 
 * This class is immutable. Once constructed you can extract the value as an
 * int, an array of bytes but you cannot change the value. Someone should
 * implement equals() and hashcode() to make this thing truly useful.
 */

public class PackedDecimalToComp {

    public static void main(String[] args) {

        try {
            // test.unpackData(" 0x12345s");
            Path path = Paths.get("C:\\Users\\AV00499269\\Desktop\\Comp3 data file\\Comp3Test.txt");
            byte[] data = Files.readAllBytes(path);
            PackedDecimalToComp test = new PackedDecimalToComp();
            test.unpackData(data);
        } catch (Exception ex) {
            System.out.println("Exception is :" + ex.getMessage());
        }    
    }

    private static String unpackData(byte[] packedData) {
        String unpackedData = "";

        final int negativeSign = 13;
        for (int currentCharIndex = 0; currentCharIndex < packedData.length; currentCharIndex++) {
            byte firstDigit = (byte) ((packedData[currentCharIndex] >>> 4) & 0x0F);
            byte secondDigit = (byte) (packedData[currentCharIndex] & 0x0F);
            unpackedData += String.valueOf(firstDigit);
            if (currentCharIndex == (packedData.length - 1)) {
                if (secondDigit == negativeSign) {
                    unpackedData = "-" + unpackedData;
                }
            } else {
                unpackedData += String.valueOf(secondDigit);
            }
        }
        System.out.println("Unpackeddata is :" + unpackedData);

        return unpackedData;
    }    
}

我传递的 Comp3 文件有值x019F

转换后,我得到了解压缩的数据783031394

4

2 回答 2

2

您可以使用免费工具IBM Record Generator for Java

这允许您生成一个表示 COBOL 或 PL/I DSECT 的 Java 类,然后您可以在自己的代码中使用它来读取/写入大多数 COBOL 和 PL/I 数据类型的值。如果您不使用结构,那么您可以通过代码了解如何使用底层JZOS类与数据类型进行交互。

尽管该工具是免费的,但它受到 IBM 的支持,因此如果您遇到问题,您可以向 IBM 提出问题,他们会修复它。

于 2018-12-06T21:01:27.590 回答
0

处理大型机二进制文件

您有 2 个选项:

  • 将文件转换为大型机上的文本文件,然后传输文件
  • 进行二进制传输并将文件保存为 EBCDIC,然后使用 JRecord 之类的东西来读取文件。您也可以使用 RecordEditor 来编辑文件

我还看到文件转换为大型机上的 Unix EBCDIC 文本文件和二进制传输(保留为 EBCDIC)。这适用于具有特殊语言特定字符的非英语 EBCDIC。Java 编辑器(例如 JEdit)在编辑 Unix Ebcdic 文件时没有问题

文件传输(大型机)

要将二进制文件(具有 comp、comp-3 等)从大型机传输到 Windows / *nix 框,您必须进行二进制传输,原因很简单:Ebcdic --> Ascii 程序无法区分二进制字段和文本字段。

Comp-3 value   hex     hex after Ascii conversion

 400          x'400c'       x'200c'       x'40' is the ebcdic space character
                                          it gets converted to the ascii
                                          space character x'20'

您需要从大型机进行二进制传输。这会将文件保留为 EBCDIC,并且任何二进制字段都将保持不变。然后,您使用 Ebcdic 读取该文件。

需要检查大型机上的RECFM。如果RECFM

  • FB - 没问题只是转移
  • VB - 在大型机上转换为 FB 或在文件传输中包含RDW(记录描述符字)选项。
  • 其他- 在大型机上转换为 FB/VB

记录编辑器

  • 确保您已安装Java
  • 您可以从这里获得 RecordEditor 。您可以下载安装程序或 USB 版本。USB 版本是一个压缩目录,您可以将其安装在任何普通目录中。

使用记录编辑器

您需要定义记录布局(或文件架构)。最简单的方法是导入 Cobol Copybook。

对于 2 字节的 comp-3 字段,使用

        01  Tst-Record.
            03  comp3-field              pic s9(3) comp-3.

导入 cobol copybook 选择Record Layouts >>> Load Cobol Copybook

Cobol 导入

然后输入Cobol copybook 文件名并按下屏幕底部的加载 Cobol按钮

在此处输入图像描述

接下来进入文件打开屏幕并输入文件名并选择刚刚导入的字帖:

在此处输入图像描述

点击回车,您应该可以更新文件:

在此处输入图像描述

生成代码

RecordEditor还可以为JRecord Library生成代码。请参阅如何为 Cobol Copybook 生成 java~jrecord 代码,以便使用 Cobol Copybook 生成 Java~JRecord 代码。

您还可以在编辑文件时生成不使用 Cobol Copybook 的代码:

从文件选项中选择生成 >>> 生成代码。然后选择一个模板并输入一个包ID

在此处输入图像描述

于 2018-12-09T13:10:27.620 回答