Распаковка данных COMP-3 на Java (встроено в Пентахо)

Мы сталкиваемся с проблемой чтения данных COMP-3 на Java, встроенных в ETL Pentaho. Есть несколько значений Float, которые хранятся в виде упакованных десятичных знаков в плоском файле вместе с другим простым текстом. В то время как простые тексты читаются правильно, мы попытались использовать Charset.forName("CP500");, но это никогда не работало. Мы все еще получаем ненужные персонажи.

Поскольку сценарии Pentaho не поддерживают COMP-3, на своих форумах они предлагали User Defined Java class, Может ли кто-нибудь помочь нам, если вы столкнулись и решили такое?

1 ответ

Это Cobol File???, у вас есть Cobol Copybook???. Возможные варианты включают

  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 в десятичное целое число. Одним из способов является

  1. Connvert x'123c' ->> Строка "123c"
  2. Брось последний символ и проверь на наличие знака

Java-код для преобразования comp3 (из байтового массива:

        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

В JRecord, если у вас есть тетрадь Cobol, есть

  • Cobol2Csv - программа для преобразования файла Cobol-Data в CSV с использованием Cobol Copybook
  • Data2Xml преобразует файл данных Cobol в Xml, используя Cobol Copybook.
  • Прочитайте Cobol-Data File с помощью Cobol Copybook.
  • Прочитать файл фиксированной ширины с описанием XML
  • Определите поля в Java
Чтение с помощью Cobol Copybook в JRecord
        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();
Определение файла в Java с помощью JRecord
        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) {
        }

Десятичная зона

Другой числовой формат мэйнфреймов-коболов - Zoned-Decimal. Это текстовый формат, в котором знак набирается последней цифрой. В зонально-десятичном виде 123 - "12C", а -123 - "12L".

Другие вопросы по тегам