【问题标题】:Spring-Batch: reading a file multi-formatSpring-Batch:读取文件多格式
【发布时间】:2019-04-02 16:56:19
【问题描述】:

我正在尝试使用 Spring Batch 读取 txt 文件,但我的问题是每个文件都有不同的数据。 例如文件的每一行对应一个类,所以对于每一行我需要不同的 FlatFileItemReader、Tokenizer 和 FieldSetMapper。

我的文件看起来像:

00|0|56||Class1|25|001|0
02|23|11||Class2|65|ENG|ENG|
02|32|25||Class3|45|0101|FRA|Es|TR

我尝试读取包含相同格式数据的文件并且它可以工作,但我不知道如何读取不同格式的文件。

FlatFileItemReader<Class1> fileReader=new FlatFileItemReader<Class1>();
fileReader.setResource(new ClassPathResource("/file.txt"));
DefaultLineMapper<Class1> lineMapper=new DefaultLineMapper<Class1>();
DelimitedLineTokenizer tokenizer=new DelimitedLineTokenizer();
tokenizer.setDelimiter("|");
lineMapper.setLineTokenizer(tokenizer);
fileReader.setLineMapper(lineMapper);

任何帮助将不胜感激。 谢谢

【问题讨论】:

  • @MahmoudBenHassine 谢谢你,但每一行代表一个类的对象
  • 这不是问题。我链接的问题中的答案使用PatternMatchingCompositeLineMapper,在这里也可以使用*Class1**Class2*等模式。但是我用一个例子编辑了@Luca Basso Ricci的答案,因为他的答案是正确的并且他值得称赞!

标签: java spring spring-batch


【解决方案1】:

创建一种CompositeLineMapper,您可以在其中存储不同的LineMapper 实现,该实现特定于您需要管理的每种类型的类。
对于文件中的每一行,此CompositeLineMapper 将前瞻鉴别器列并调度到正确的LineMapper 实现。 我不能给你代码,因为我没有使用 SB atm,所以我把实现留给你。

编辑:添加如何分类项目的示例

这是一个基于Classifier的复合线映射器:

import org.springframework.batch.item.file.LineMapper;
import org.springframework.classify.Classifier;

public class ClassifierCompositeLineMapper implements LineMapper<Object> {

    private Classifier<String, LineMapper<?>> classifier;

    public ClassifierCompositeLineMapper(Classifier<String, LineMapper<?>> classifier) {
        this.classifier = classifier;
    }

    @Override
    public Object mapLine(String line, int lineNumber) throws Exception {
        return classifier.classify(line).mapLine(line, lineNumber);
    }
}

下面是如何使用它:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import org.springframework.batch.item.file.LineMapper;
import org.springframework.batch.item.file.mapping.PassThroughLineMapper;
import org.springframework.classify.Classifier;

public class ClassifierCompositeLineMapperTest {

    private ClassifierCompositeLineMapper compositeLineMapper;

    @Before
    public void setUp() {
        Classifier<String, LineMapper<?>> classifier = new Classifier<String, LineMapper<? extends Object>>() {
            @Override
            public LineMapper<?> classify(String classifiable) {
                if (classifiable.contains("Class1")) {
                    return new Class1LineMapper();
                }

                if (classifiable.contains("Class2")) {
                    return new Class2LineMapper();
                }
                return new PassThroughLineMapper(); // or any other default line mapper
            }
        };
        compositeLineMapper = new ClassifierCompositeLineMapper(classifier);
    }

    @Test
    public void mapLine() throws Exception {
        Object line1 = compositeLineMapper.mapLine("00|0|56||Class1|25|001|0", 1);
        Assert.assertTrue(line1 instanceof Class1);
        Object line2 = compositeLineMapper.mapLine("02|23|11||Class2|65|ENG|ENG|", 2);
        Assert.assertTrue(line2 instanceof Class2);
    }

    static class Class1 {}
    static class Class1LineMapper implements LineMapper<Class1> {

        @Override
        public Class1 mapLine(String line, int lineNumber) throws Exception {
            return new Class1(); // TODO mapping logic
        }
    }

    static class Class2 {}
    static class Class2LineMapper implements LineMapper<Class2> {

        @Override
        public Class2 mapLine(String line, int lineNumber) throws Exception {
            return new Class2(); // TODO mapping logic
        }
    }

}

【讨论】:

  • 谢谢你的帮助,只是我还有一个问题:当我使用 FlatFileItemReader 时,我用任何类调用它?
  • 这个答案是正确的,而且由于卢卡无法举出atm的例子,所以我做到了。 @LucaBassoRicci 如有必要,请随时修改/修改示例。
  • @noor: 检查ClassifierCompositeItemWriter
  • 我支持 Luca 的评论,在写作时对项目进行分类,ClassifierCompositeItemWriter 是要走的路。这两个组件(PatternMatchingCompositeLineMapperClassifierCompositeItemWriter)通常组合使用,这里有一个类似的问题/答案:stackoverflow.com/a/51766820/5019386。希望对您有所帮助。
  • MahmoudBenHassine,LucaBassoRicci 非常感谢它与 ClassifierCompositeItemWriter 一起使用
猜你喜欢
  • 2021-01-04
  • 2021-11-09
  • 1970-01-01
  • 2015-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多