首页 文章

如何使用java解码ascii文件中的comp 3压缩字段?

提问于
浏览
-1

我有一个从遗留系统中提取的庞大的大型机文件 . 该文件以ascii格式编码 . 我想将其转换为comp3 . java中是否有可用的算法来做到这一点?另外,我需要有关如何解压缩comp3字段的帮助 . 我尝试了一个java代码解压缩comp3但我发现不正确的结果

请参阅代码以解压缩comp3字段

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.
 **/ 


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

1 回答

  • 1

    您的代码中的注释不正确 . 带有正号的打包数据在最后一个半字节中具有x'A',x'C',x'E'或x'F' . 大型机也有一个“首选符号”的概念,在最后一个半字节中为x'C',在最后一个半字节中为x'D'为负 .

    大型机数据通常在单个记录中包含文本和二进制数据,例如名称,货币金额和数量:

    Hopper Grace ar% .

    ......那将是......

    x'C8969797859940404040C799818385404040404081996C004B'

    ......十六进制这是代码页37,通常称为EBCDIC .

    在不知道姓氏被限制在前10个字节的情况下,给定的名称限制了后续的10个字节,货币数量在接下来的3个字节中以压缩十进制(也称为二进制编码的十进制)表示,并且数量在接下来的两个字节,你无法准确传输数据,因为代码页转换会破坏货币金额 . 转换到通常在Microsoft Windows上使用的代码页1250,最终会得到......

    x'486F707065722020202047726163652020202020617225002E'

    ...文本数据被翻译但打包数据被销毁的地方 . 打包数据在最后一个半字节(最后一个字节的下半部分)中不再有有效符号,货币数量本身已经改变了数量(从小数75到小数11,776,因为代码页转换和修改一个大端数字作为一个小端数字) .

    This question有一些可能对你有帮助的答案 . 我的建议是在将数据传输到另一个平台之前将所有数据转换为大型机上的文本 . 有一些擅长的大型机实用程序 .

相关问题