我需要使用Kettle/PDI社区版本来读取大的固定长度的数据文件,并对它们执行一些ETL操作。在开发阶段,我面临以下问题:
我尝试使用"Select“插件并将二进制类型的列更改为Integer,但这种方法没有实现。最后,我以以下解决方案结束:
正如您所看到的,我使用了一个公式来获得长值。
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[]转换为宾得凯特尔“数字”数据类型?(BigNumber和Integer也不错)。
发布于 2016-04-26 21:26:58
我发现了以下可能性:
1)可以向ValueMetaInterface类添加其他类型:
org.pentaho.di.core.row.ValueMetaInterface中添加转换函数。
org.pentaho.di.core.row.ValueMeta2)将代码片段实现getNumberFromLE添加到“用户定义的Java”的“通用”代码片段中
3)添加作为插件的新数据类型,如下面两个链接所述:Jira可插入类型 GitHub pdi-valuemeta-map AddingDataTypes
https://stackoverflow.com/questions/36876090
复制相似问题