在读取嵌入在Pentaho ETL中的Java中的COMP-3数据时,我们面临着一个挑战。很少有Float值与其他纯文本一起存储为平面文件中的打包小数。虽然可以正确阅读纯文本,但我们尝试使用Charset.forName("CP500");,但从未成功。我们仍然会收到垃圾字符。

由于Pentaho脚本不支持COMP-3,因此在他们的论坛中建议使用User Defined Java class。如果您遇到并解决了此类问题,有人可以帮助我们吗?

最佳答案

它是Cobol文件???,您是否有Cobol Copybook ???。
可能的选项包括


正如Bill所说,在源计算机上将Comp-3转换为文本
编写自己的转换代码
使用类似JRecord的库。注意:我是JRecord的作者




转换Comp-3

在Comp-3中

Value    Comp-3 (signed)   Comp-3 (Unsigned)   Zoned-Decimal
 123     x'123c'           x'123f' ??            "12C"
-123     x'123d'                                 "12L"


有多种方法可以将comp-3转换为十进制整数。单程
是为了


转换x'123c'->>字符串“ 123c”
删除最后一个字符并测试符号


转换comp3的Java代码(从字节数组:

        public static String getMainframePackedDecimal(final byte[] record,
                                               final int start,
                                               final int len) {

            String hex  = getDecimal(record, start, start + len);
                //Long.toHexString(toBigInt(start, len).longValue());
            String ret  = "";
            String sign = "";

            if (! "".equals(hex)) {
                switch (hex.substring(hex.length() - 1).toLowerCase().charAt(0)) {
                    case 'd' : sign = "-";
                        case 'a' :
                        case 'b' :
                        case 'c' :
                        case 'e' :
                        case 'f' :
                            ret = sign + hex.substring(0, hex.length() - 1);
                        break;
                        default:
                            ret = hex;
                }
            }

            if ("".equals(ret)) {
                ret = "0";
            }
        }

        public static String getDecimal(final byte[] record, final int start, final int fin) {
            int i;
            String s;
            StringBuffer ret = new StringBuffer("");
            int b;

            for (i = start; i < fin; i++) {
                b = toPostiveByte(record[i]);
                s = Integer.toHexString(b);
                if (s.length() == 1) {
                    ret.append('0');
                }
                ret.append(s);

            }

            return ret.toString();
        }




记录

JRecord中,如果您有Cobol字帖,



Cobol2Csv一个使用Cobol Copybook将Cobol-Data文件转换为CSV的程序
Data2Xml使用Cobol Copybook将Cobol数据文件转换为Xml。
用Cobol Copybook读取Cobol数据文件。
读取带有XML说明的定宽文件
在Java中定义字段


在JRecord中使用Cobol Copybook进行阅读

        ICobolIOBuilder ioBldr = JRecordInterface1.COBOL
                .newIOBuilder(copybookName)
                    .setDialect( ICopybookDialects.FMT_MAINFRAME)
                    .setFont("cp037")
                    .setFileOrganization(Constants.IO_FIXED_LENGTH)
                .setDropCopybookNameFromFields(true);
        AbstractLine saleRecord;

        AbstractLineReader reader  = ioBldr.newReader(salesFile);
        while ((saleRecord = reader.read()) != null) {
            ....
        }

        reader.close();


使用JRecord在Java中定义文件

        AbstractLineReader reader = JRecordInterface1.FIXED_WIDTH.newIOBuilder()
                                .defineFieldsByLength()
                                    .addFieldByLength("Sku"  , Type.ftChar,   8, 0)
                                    .addFieldByLength("Store", Type.ftNumRightJustified, 3, 0)
                                    .addFieldByLength("Date" , Type.ftNumRightJustified, 6, 0)
                                    .addFieldByLength("Dept" , Type.ftNumRightJustified, 3, 0)
                                    .addFieldByLength("Qty"  , Type.ftNumRightJustified, 2, 0)
                                    .addFieldByLength("Price", Type.ftNumRightJustified, 6, 2)
                                .endOfRecord()
                                .newReader(this.getClass().getResource("DTAR020_tst1.bin.txt").getFile());
        AbstractLine saleRecord;

        while ((saleRecord = reader.read()) != null) {
        }




分区小数

另一种Mainframe-Cobol数字格式是Zoned-Decimal。这是一种文本格式,其中符号的最后一位数字过大。区域小数点123是“ 12C”,而-123是“ 12L”。

关于java - Java中的COMP-3数据解压缩(嵌入Pentaho),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35414574/

10-13 03:19