Pentaho Kettle - 从二进制类型的字段将十六进制转换为数字
Pentaho Kettle - Convert hex to Number from field of type binary
我需要使用 Kettle/PDI 社区版本来读取大的固定长度数据文件并对它们执行一些 ETL 操作。在开发阶段我遇到了以下问题:
Kettle 插件"Fixed File Input" 允许多种数据类型,注意它们实际上是字符串或字节数组。
我的输入包含:字符串和字节数组,对应于 long、int 和 short 的 Little Endian 表示(Intel 特定的字节顺序)。
要读取的记录结构示例:
Column1(char:8), Column2(long:8 hex), Column3(char:2), Column4(int:4 hex).
我尝试使用 "Select Values" 插件并将 Binary 类型的列更改为 Integer,但这种方法没有实现。最后我以以下解决方案结束:
- 我使用了 "User Defined Java Class",下面粘贴了代码。
如您所见,我使用了一个公式来获取 long 值。
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) 可以向 ValueMetaInterface 添加其他类型 class:
org.pentaho.di.core.row.ValueMetaInterface
并将转换函数添加到
org.pentaho.di.core.row.ValueMeta
2) 添加代码片段实现 getNumberFromLE 到 "Common use" "User Defined Java Class"
的代码片段
3) 添加新数据类型作为插件,如下面两个链接所述:
Jira pluggable types
GitHub pdi-valuemeta-map
AddingDataTypes
我需要使用 Kettle/PDI 社区版本来读取大的固定长度数据文件并对它们执行一些 ETL 操作。在开发阶段我遇到了以下问题:
Kettle 插件"Fixed File Input" 允许多种数据类型,注意它们实际上是字符串或字节数组。
我的输入包含:字符串和字节数组,对应于 long、int 和 short 的 Little Endian 表示(Intel 特定的字节顺序)。 要读取的记录结构示例: Column1(char:8), Column2(long:8 hex), Column3(char:2), Column4(int:4 hex).
我尝试使用 "Select Values" 插件并将 Binary 类型的列更改为 Integer,但这种方法没有实现。最后我以以下解决方案结束:
- 我使用了 "User Defined Java Class",下面粘贴了代码。
如您所见,我使用了一个公式来获取 long 值。
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) 可以向 ValueMetaInterface 添加其他类型 class:
org.pentaho.di.core.row.ValueMetaInterface
并将转换函数添加到
org.pentaho.di.core.row.ValueMeta
2) 添加代码片段实现 getNumberFromLE 到 "Common use" "User Defined Java Class"
的代码片段3) 添加新数据类型作为插件,如下面两个链接所述: Jira pluggable types GitHub pdi-valuemeta-map AddingDataTypes