【问题标题】:Flat file parsing : when some fields contain the delimiter平面文件解析:当某些字段包含分隔符时
【发布时间】:2019-10-23 03:19:20
【问题描述】:

我有一个使用这个阅读器读取文件的 spring-batch 应用程序:

<bean id="tradeItemReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
    <property name="resource">
        <bean class="org.springframework.core.io.FileSystemResource">
            <constructor-arg value="${input.file.path}/#{jobExecutionContext['trades']}" type="java.lang.String"/>
        </bean>
    </property>
    <property name="linesToSkip" value="1" />
    <property name="lineMapper">
        <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
            <!-- split it -->
            <property name="lineTokenizer">
                <bean
                    class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                    <beans:property name="strict" value="false" />
                    <beans:property name="includedFields" value="0,2,3,6" />
                    <property name="names"
                        value="field0,field2,field3,field6" />
                </bean>
            </property>
            <property name="fieldSetMapper">
                <bean
                    class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                    <property name="prototypeBeanName" value="trade" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

字段由逗号 , 分隔,这里有一个问题:有些字段看起来像 [LON, TGT],由于方括号内的逗号,该行最终被错误地解析。

例子:

输入:Global,,VERIFIED,[LON, TGT],ERerd,3456585,QTR,20190929,20231020

所需输出:GlobalVERIFIED[LON, TGT]QTR

实际输出:GlobalVERIFIED[LON3456585

我怎样才能做到这一点?我无法控制输入文件。

编辑

这不是重复的,因为建议的解决方案不起作用:这里我们没有单引号字符,但我们有 2 个不同的,即左括号和右括号。

【问题讨论】:

  • 这是什么文件?它是用逗号分隔的文本文件吗?
  • 是的,它是一个逗号分隔的 csv 文件
  • 好的,检查 OpenCSV 框架以解析 CSV 文件。
  • 您是否可以控制在源文件中使用哪个字符作为分隔符?
  • @All - 我建议根据索引位置 2 和 3 更改像 Global, VERIFIED, LON, TGT, QTR 这样的文件,您可以获取数据并做必要的事情。这样您就可以拥有正确的 CSV 文件

标签: java parsing spring-batch flat-file


【解决方案1】:

正如 Luca Basso Ricci 所解释的,我的输入 csv 无效,但我仍然必须处理它,因为我无法控制它。

所以我写了自己的分隔线分词器,也就是 DelimitedLineTokenizer 改写了 isDelimiter() 方法,并在 conf 文件中替换了它:

  private boolean isDelimiter(char[] chars, int i, String token, int endIndexLastDelimiter) {
    boolean result = false;
    
    int openingBrackets = StringUtils.countOccurrencesOf(new String(Arrays.copyOfRange(chars, 0, i)),  "[");
    int closingBrackets = StringUtils.countOccurrencesOf(new String(Arrays.copyOfRange(chars, 0, i)),  "]");
    
    boolean inBrackets = (openingBrackets - closingBrackets > 0);
    
    if ((i - endIndexLastDelimiter >= this.delimiter.length()) && 
      (i >= token.length() - 1)) {
      String end = new String(chars, i - token.length() + 1, token.length());
      if (token.equals(end)) {
        result = !inBrackets;
      }
    }
    return result;
  }

【讨论】:

    猜你喜欢
    • 2021-11-18
    • 2014-07-12
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 2021-07-24
    • 2012-05-13
    相关资源
    最近更新 更多