Univocity Parser - 如何在已解析的 bean 中获取行号
Univocity Parser - How to get row number in parsed bean
使用 Univocity FixedWidthParser
时,如何将 record/line 数字作为字段添加到已解析的 bean 中?
- 是否有一个选项可以将 bean 属性 标记为记录号,例如:
// Bean representing a record
public class MyRecord {
@RecordNumber //like this, record or line number from the context is assigned as value
long recordNumber;
@Parsed
String name;
//other parsed fields
}
}
- 我正在使用
InputValueSwitch
。有没有一种方法可以在 rowProcessorSwitched()
中获取上下文,以便我可以尝试:
final BeanListProcessor<MyRecord> myProcessor = new BeanListProcessor<MyRecord>(
MyRecord.class);
public void rowProcessorSwitched(RowProcessor from, RowProcessor to) {
ParsingContext context = ... //how to get this?
long lineNumber = context.currentLine(); //if i can get this...
if (from == myProcessor){
(MyRecord)myProcessor.getBeans().get(0).setRecordNumber(lineNumber); //...then this should be possible
//other switch logic
}
}
更新:
在 InputSwitch 中,我尝试实现 processStarted
ParsingContext refToContext = null;
public void processStarted(ParsingContext context) {
refToContext = context;
super.processStarted(context);
}
并在 rowProcessorSwitched() 中使用它,
long lineNumber = refToContext.currentLine() - 1;
这是一种有效的方法吗?它是否可靠 - esp,当解析过程中遇到错误时。
此解决方案不使用 InputSwitch
或 InputValueSwitch
,但会生成带有 rowNumber
属性 的 bean,代表它们的行号。
final BeanListProcessor<MyRecord> myProcessor = new BeanListProcessor(MyRecord.class) {
public void beanProcessed(Object bean, Context context) {
bean.setRowNumber(beans.size()); // +/- to adjust for header row(s)
super.beanProcessed(bean, context);
}
}
我唯一需要做的就是确保这个处理器被分配给解析器的设置对象,然后在 CsvParser
的实例上调用 parse()
我'已分配这些设置。
CsvParserSettings csvSettings = new CsvParserSettings();
csvSettings.setProcessor(myProcessor);
CsvParser csvParser = new CsvParser(csvSettings);
csvParser.parse();
请注意,我省略了内部函数上的 @Override
注释。无论出于何种原因,在我的生产实现中,IntelliJ 表示这不会覆盖超级 class,但测试清楚地表明这是有效的。我使用 IntelliJ 的“生成”选项来存根这个方法,所以谁知道...
另请注意,我的生产代码在 Groovy 中,因此请原谅任何语法问题;我在脑海中转换为 Java。
使用 Univocity FixedWidthParser
时,如何将 record/line 数字作为字段添加到已解析的 bean 中?
- 是否有一个选项可以将 bean 属性 标记为记录号,例如:
// Bean representing a record
public class MyRecord {
@RecordNumber //like this, record or line number from the context is assigned as value
long recordNumber;
@Parsed
String name;
//other parsed fields
}
}
- 我正在使用
InputValueSwitch
。有没有一种方法可以在rowProcessorSwitched()
中获取上下文,以便我可以尝试:
final BeanListProcessor<MyRecord> myProcessor = new BeanListProcessor<MyRecord>(
MyRecord.class);
public void rowProcessorSwitched(RowProcessor from, RowProcessor to) {
ParsingContext context = ... //how to get this?
long lineNumber = context.currentLine(); //if i can get this...
if (from == myProcessor){
(MyRecord)myProcessor.getBeans().get(0).setRecordNumber(lineNumber); //...then this should be possible
//other switch logic
}
}
更新: 在 InputSwitch 中,我尝试实现 processStarted
ParsingContext refToContext = null;
public void processStarted(ParsingContext context) {
refToContext = context;
super.processStarted(context);
}
并在 rowProcessorSwitched() 中使用它,
long lineNumber = refToContext.currentLine() - 1;
这是一种有效的方法吗?它是否可靠 - esp,当解析过程中遇到错误时。
此解决方案不使用 InputSwitch
或 InputValueSwitch
,但会生成带有 rowNumber
属性 的 bean,代表它们的行号。
final BeanListProcessor<MyRecord> myProcessor = new BeanListProcessor(MyRecord.class) {
public void beanProcessed(Object bean, Context context) {
bean.setRowNumber(beans.size()); // +/- to adjust for header row(s)
super.beanProcessed(bean, context);
}
}
我唯一需要做的就是确保这个处理器被分配给解析器的设置对象,然后在 CsvParser
的实例上调用 parse()
我'已分配这些设置。
CsvParserSettings csvSettings = new CsvParserSettings();
csvSettings.setProcessor(myProcessor);
CsvParser csvParser = new CsvParser(csvSettings);
csvParser.parse();
请注意,我省略了内部函数上的 @Override
注释。无论出于何种原因,在我的生产实现中,IntelliJ 表示这不会覆盖超级 class,但测试清楚地表明这是有效的。我使用 IntelliJ 的“生成”选项来存根这个方法,所以谁知道...
另请注意,我的生产代码在 Groovy 中,因此请原谅任何语法问题;我在脑海中转换为 Java。