2

Pentaho ETL 内に埋め込まれた Java で COMP-3 データを読み取る際に、課題に直面しています。他のプレーン テキストと共にフラット ファイルにパック 10 進数として格納されている Float 値はほとんどありません。プレーンテキストが適切に読み取られている間に、 を使用してみCharset.forName("CP500");ましたが、うまくいきませんでした。私たちはまだジャンクキャラクターを手に入れています。

Pentaho スクリプトは COMP-3 をサポートしていないため、フォーラムで を使用することを提案しましたUser Defined Java class。あなたが遭遇して解決した場合、誰かが私たちを助けることができますか?

4

1 に答える 1

1

それは COBOL ファイルですか ???、Cobol コピーブックはありますか ???. 可能なオプションは次のとおりです。

  1. ビルが言ったように、ソース マシンで Comp-3 をテキストに変換します。
  2. 独自の変換コードを書く
  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 を 10 進整数に変換する方法は複数あります。1つの方法は

  1. x'123c' を変換 ->> 文字列 "123c"
  2. 最後の文字をドロップして符号をテストします

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

Jレコード

JRecordには、Cobol コピーブックがある場合

  • Cobol2Csv Cobol Copybook を使用して Cobol-Data ファイルを CSV に変換するプログラム
  • Data2Xmlは、Cobol Copybook を使用して Cobol データ ファイルを Xml に変換します。
  • Cobol Copybook を使用して Cobol-Data ファイルを読み取ります。
  • Xml 記述を含む固定幅ファイルを読み取る
  • Java でフィールドを定義する
JRecord で COBOL コピーブックを使用して読み取る
        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) {
        }

ゾーン 10 進数

もう 1 つのメインフレーム COBOL 数値形式は Zoned-Decimal です。最後の桁に記号が上書きされたテキスト形式です。ゾーン 10 進数では、 123は " 12C " で、-123は " 12L " です。

于 2016-02-15T21:00:03.820 に答える