用Java解压缩COMP-3数据(嵌入Pentaho)

时间:2016-02-15 16:41:20

标签: java pentaho comp-3

我们在阅读嵌入Pentaho ETL内部的Java中的COMP-3数据时遇到了挑战。在平面文件中存在少量Float值作为压缩小数存储以及其他纯文本。虽然普通文本正在被正确阅读,但我们尝试使用 private bool GetIfXPSPrinterIsInstalled() { bool isXPSPrinterMissing = true; try { var printerQuery = new System.Management.ManagementObjectSearcher("SELECT * from Win32_Printer"); var iterator = printerQuery.Get().GetEnumerator(); while (iterator.MoveNext() && isXPSPrinterMissing ) { //isXPSPrinterMissing = iterator.Current.GetPropertyValue("DriverName").ToString() != "Microsoft XPS Document Writer"; isXPSPrinterMissing = !iterator.Current.GetPropertyValue("DeviceID").ToString().ToUpper().Contains("XPS"); } if (isXPSPrinterMissing ) { MessageBox.Show("Warning, there is no XPS printer installed on this computer"); } } catch (Exception ex) { MessageBox.Show("System couldn't verify if there is a XPS printer installed because an error occured"); } return !isXPSPrinterMissing; } ,但它从未奏效。我们仍然得到垃圾字符。

由于Pentaho脚本不支持COMP-3,因此在他们的论坛中他们建议使用Charset.forName("CP500");。如果你碰到并解决了这个问题,有人可以帮助我们吗?

1 个答案:

答案 0 :(得分:1)

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

  1. 正如比尔所说,将源代码机上的Comp-3转换为文本
  2. 编写您自己的转换代码
  3. 使用JRecord之类的库。 注意:我是JRecord的作者
  4. 转换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. 删除最后一个字符并测试符号
    3. 转换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

      JRecord中,如果您有Cobol Copybook, 有

      • Cobol2Csv使用Cobol Copybook将Cobol-Data文件转换为CSV的程序
      • Data2Xml使用Cobol Copybook将Cobol Data文件转换为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) {
              }
      

      Zoned Decimal

      另一个Mainframe-Cobol数字格式为Zoned-Decimal。它是一种文本格式,其中最后一位数字上的符号为 Over-typed 。在分区十进制 123 是“ 12C ”,而 -123 是“ 12L ”。