Spring Batch:在有效标题后写入行

时间:2013-02-19 14:37:00

标签: java parsing spring-batch

我有一个非常大的txt文件,我正在使用PatternMatchingCompositeLineMapper进行解析,因为每行都有不同的列数。
在此文件中,我有来自多个期间的数据,此文件中的每个期间都由标题 DATA 表示,并带有此期间的日期。在此标题之后,有一些行包含与此期间相关的数据,并以标题 STOP 结束 问题是我需要将在特定日期之前和之后开始的所有时段的数据保存到另一个文件。
有没有办法在Spring Batch中执行此操作?
示例文件如下所示:

DATA|20121113-20121212
STRT|33|20121213|123425654|123
ASD|asd|asd|asd
QWE|qwe|qwe
ZXC|zxc|zxc|zxc|zxc
STOP

DATA|20121213-20130112
STRT|33|20130113|65465463546|123
ASD|asd|asd|asd
QWE|qwe|qwe
ZXC|zxc|zxc|zxc|zxc
STOP

DATA|20121113-20121212
STRT|33|20121213|34653465546|123.10
ASD|asd|asd|asd
QWE|qwe|qwe
ZXC|zxc|zxc|zxc|zxc
STOP

DATA|20120713-20120812
STRT|33|20121213|34654356546|123.10
STOP

DATA|20121213-20130112
STRT|33|20130113|345646345|123.10
ASD|asd|asd|asd
QWE|qwe|qwe
ZXC|zxc|zxc|zxc|zxc
STOP

1 个答案:

答案 0 :(得分:1)

您可以通过ClassifierCompositeItemWriter执行此操作。我将假设您有一个域对象(例如,MyDomainObject),它具有相同输入中显示的开始日期和结束日期。

首先需要创建一个声明classify方法的类,并使用@Classifier对其进行注释。这将有效地将项目路由到其中一个底层项目编写者(在您的情况下,基于记录的开始和结束日期是否跨越参考日期)。

import org.springframework.batch.support.annotation.Classifier;
public class MyDateClassifierDelegate {
    //set this via Spring, or whatever
    private final Date referenceDate;

    @Classifier
    public String classify(MyDomainObject classifiable) {
        if(classifiable.startDate.compareTo(referenceDate) < 0
                && classifiable.endDate.compareTo(referenceDate) >= 0) {
            return "FILE1";
        }
        else {
            return "FILE2";
        }
    }
}

接下来,您需要根据分类器设置的值将ClassifierCompositeItemWriter配置为委派给两个基础项编写器之一。在这种情况下,您将根据需要设置file1Writerfile2Writer,我收集的只是平面文件项目编写者。

<beans:bean id="dateRangeBasedFileWriter" class="org.springframework.batch.item.support.ClassifierCompositeItemWriter">
    <beans:property name="classifier">
        <beans:bean class="org.springframework.batch.classify.BackToBackPatternClassifier">
            <beans:property name="routerDelegate">
                <!-- this is where you specify the classifier that is to be used -->
                <beans:bean class="MyDateClassifierDelegate" />
            </beans:property>
            <beans:property name="matcherMap">
                <beans:map>
                    <!-- this will contain your "spanning reference date" items -->
                    <beans:entry key="FILE1" value-ref="file1Writer" />
                    <!-- this will contain your "not spanning reference date" items -->
                    <beans:entry key="FILE2" value-ref="file2Writer" />
                </beans:map>
            </beans:property>
        </beans:bean>
    </beans:property>
</beans:bean>