Spring 批处理 LineMapper 的可选多行条目
Optional Multi-line Entry for Spring Batch LineMapper
我有一个通常具有以下格式的文件:
property_A_1@property_B_1@property_C_1@property_D_1
property_A_2@property_B_2@property_C_2@property_D_2
property_A_3@property_B_3@property_C_3@property_D_3
这应该映射到具有四个属性的自定义 class,@
作为分隔符。但是,在某些情况下 property_B
可能包含换行符作为其字符的一部分,例如:
property_A_1@property_B_1@property_C_1@property_D_1
property_A_2@property_B_2_i
property_B_2_ii
property_B_2_iii
property_B_2_iiii@property_C_2@property_D_2
property_A_3@property_B_3@property_C_3@property_D_3
这些行的数量可以变化并且不固定。在这种情况下,我仍然需要像以前一样映射第二个条目,除了 property_b_2
应该包含第一个 @
和第二个 @
.
之间的数据。
如果我可以用空格替换它们,我可以忍受没有新行,所以假设实际条目看起来像:
property_A_2@property_B_2_i property_B_2_ii property_B_2_iii@property_B_2_iiii@property_C_2@property_D_2
有没有办法用 ItemReader
和 LineMapper
来完成这个?
我通过覆盖 ItemReader
的 DefaultRecordSeparatorPolicy#isEndOfRecord()
解决了这个问题。我还需要阅读未终止的引号检查,因为内容可能有一对不均匀的引号字符:
itemReader.setRecordSeparatorPolicy(new DefaultRecordSeparatorPolicy() {
private static final String CONTINUATION = "\";
private String continuation = CONTINUATION;
private String final String delimiter ="@";
@Override
public boolean isEndOfRecord(String line) {
return StringUtils.countOccurrencesOf(line, delimiter) >=3 &&
!isQuoteUnterminated(line) &&
!isContinued(line);
}
private boolean isQuoteUnterminated(String line) {
return false;
}
private boolean isContinued(String line) {
if (line == null) {
return false;
}
return line.trim().endsWith(continuation);
}
});
我有一个通常具有以下格式的文件:
property_A_1@property_B_1@property_C_1@property_D_1
property_A_2@property_B_2@property_C_2@property_D_2
property_A_3@property_B_3@property_C_3@property_D_3
这应该映射到具有四个属性的自定义 class,@
作为分隔符。但是,在某些情况下 property_B
可能包含换行符作为其字符的一部分,例如:
property_A_1@property_B_1@property_C_1@property_D_1
property_A_2@property_B_2_i
property_B_2_ii
property_B_2_iii
property_B_2_iiii@property_C_2@property_D_2
property_A_3@property_B_3@property_C_3@property_D_3
这些行的数量可以变化并且不固定。在这种情况下,我仍然需要像以前一样映射第二个条目,除了 property_b_2
应该包含第一个 @
和第二个 @
.
如果我可以用空格替换它们,我可以忍受没有新行,所以假设实际条目看起来像:
property_A_2@property_B_2_i property_B_2_ii property_B_2_iii@property_B_2_iiii@property_C_2@property_D_2
有没有办法用 ItemReader
和 LineMapper
来完成这个?
我通过覆盖 ItemReader
的 DefaultRecordSeparatorPolicy#isEndOfRecord()
解决了这个问题。我还需要阅读未终止的引号检查,因为内容可能有一对不均匀的引号字符:
itemReader.setRecordSeparatorPolicy(new DefaultRecordSeparatorPolicy() {
private static final String CONTINUATION = "\";
private String continuation = CONTINUATION;
private String final String delimiter ="@";
@Override
public boolean isEndOfRecord(String line) {
return StringUtils.countOccurrencesOf(line, delimiter) >=3 &&
!isQuoteUnterminated(line) &&
!isContinued(line);
}
private boolean isQuoteUnterminated(String line) {
return false;
}
private boolean isContinued(String line) {
if (line == null) {
return false;
}
return line.trim().endsWith(continuation);
}
});