Pentaho Kettle - 从二进制类型的字段将十六进制转换为数字

Posted

技术标签:

【中文标题】Pentaho Kettle - 从二进制类型的字段将十六进制转换为数字【英文标题】:Pentaho Kettle - Convert hex to Number from field of type binary 【发布时间】:2016-04-26 21:26:58 【问题描述】:

我需要使用 Kettle/PDI 社区版本来读取大的固定长度数据文件并对其进行一些 ETL 操作。在开发阶段,我遇到了以下问题:

Kettle 插件“固定文件输入”允许多种数据类型,备注它们实际上是字符串或字节数组。

我的输入包含:字符串和字节数组,对应于 long、int 和 short 的 Little Endian 表示(Intel 特定的字节序)。 要读取的记录结构示例: Column1(char:8)、Column2(long:8 hex)、Column3(char:2)、Column4(int:4 hex)。

我尝试使用“选择值”插件并将列的二进制类型更改为整数,但没有实现这种方法。最后我以以下解决方案结束:

我使用了“用户定义的 Java 类”,下面粘贴了代码。

如您所见,我使用了一个公式来获得长值。

   public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
       
    Object[] r = getRow();

    if (r == null) 
      setOutputDone();
      return false;
    

    // It is always safest to call createOutputRow() to ensure that your output row's Object[] is large
    // enough to handle any new fields you are creating in this step.
    r = createOutputRow(r, data.outputRowMeta.size());      

    // Get the value from an input field
    byte[] buf;
    long  longValue;

    // BAN_L - 8 bytes
    buf= get(Fields.In, "BAN").getBinary(r);      
    longValue=  ((buf[0] & 0xFFL) << 0) | ((buf[1] & 0xFFL) << 8)
                | ((buf[2] & 0xFFL) << 16) | ((buf[3] & 0xFFL) << 24)
                | ((buf[4] & 0xFFL) << 32) | ((buf[5] & 0xFFL) << 40)
                | ((buf[6] & 0xFFL) << 48) | ((buf[7] & 0xFFL) << 56);      
    get(Fields.Out, "BAN_L").setValue(r, longValue);

    //DEPOSIT_PAID_AMT -4 bytes
    buf = get(Fields.In, "DEPOSIT_PAID_AMT").getBinary(r);
    longValue=  ((buf[0] & 0xFFL) << 0) | ((buf[1] & 0xFFL) << 8)
                | ((buf[2] & 0xFFL) << 16) | ((buf[3] & 0xFFL) << 24);
    get(Fields.Out, "DEPOSIT_PAID_AMT_L").setValue(r, longValue);

    //BILL_SEQ_NO_L -2 bytes
    buf = get(Fields.In, "BILL_SEQ_NO").getBinary(r);
    longValue =  ((buf[0] & 0xFFL) << 0) | ((buf[1] & 0xFFL) << 8);
    get(Fields.Out, "BILL_SEQ_NO_L").setValue(r, longValue);    


    // Send the row on to the next step.
    putRow(data.outputRowMeta, r);

    //binaryToDecimal();

    return true;

当我在一个数据中提取 8-20 个二进制字段时出现问题。 有没有其他方法可以替代这种方法,所以我可以这样称呼:

getNumberFromLE(byte [] buff, buff.length);    

是否有任何其他插件可用于将 byte[] 转换为 Pentaho Kettle "Number" 数据类型? (BigNumber 和 Integer 也不错)。

【问题讨论】:

【参考方案1】:

我发现了以下可能性:

1) 可以向 ValueMetaInterface 类添加其他类型:

org.pentaho.di.core.row.ValueMetaInterface

并添加转换函数到

org.pentaho.di.core.row.ValueMeta

2) 将代码 sn-p 实现 getNumberFromLE 添加到“用户定义的 Java 类”的“常用”代码片段

3) 添加作为插件的新数据类型,如下面的两个链接所述: Jira pluggable types GitHub pdi-valuemeta-map AddingDataTypes

【讨论】:

以上是关于Pentaho Kettle - 从二进制类型的字段将十六进制转换为数字的主要内容,如果未能解决你的问题,请参考以下文章

使用 StAX / Kettle (Pentaho) 读取 XML 文件

彻底理解从二进制到序列化跨平台

Pentaho Data Integration (Kettle) 简介

在 Kettle/Spoon/Pentaho 中循环

Pentaho - 如何根据 Kettle 属性文件设置工作转换

pentaho专题系列之kettle篇--kettle源码编译