как читать CSV-файл, разделенный запятыми, и файл csv, разделенный строкой, в одном средстве чтения элементов в весенней партии - PullRequest
0 голосов
/ 16 июня 2020

Я новичок в партии веточек. У меня есть папка, содержащая несколько файлов csv, я реализовал MultiResourceItemReader () для чтения этого файла. Это работает, только если все файлы CSV разделены конвейерной строкой ("|").

Я хочу читать как CSV, разделенные запятыми (","), так и CSV, разделенные строкой, с помощью одного считывателя. Является ли это возможным ? если да, то как?

Вот мой код

@Bean
@StepScope
public MultiResourceItemReader<Person> multiResourceItemReader(@Value("#{jobParameters[x]}") String x,@Value("#{jobParameters[y]}") String y,@Value("#{jobParameters[z]}") String z) {

    Resource[] resourcessss = null;
    ClassLoader cl = this.getClass().getClassLoader();
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
    try {
        resourcessss = resolver.getResources("file:" + z);
    }catch(Exception e) {

    }
    MultiResourceItemReader<Person> resourceItemReader = new MultiResourceItemReader<Person>();
    resourceItemReader.setResources(resourcessss);
    resourceItemReader.setDelegate(reader());

    return resourceItemReader;
}



@Bean
public FlatFileItemReader<Person> reader() {
    FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>();
    reader.setLineMapper(new DefaultLineMapper() {
        {
            setLineTokenizer(new DelimitedLineTokenizer() {
                {
                    setNames(new String[]{"Id","postCode"});
                }
                {
                    setDelimiter("|");
                }
            });
            setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {
                {
                    setTargetType(Person.class);
                }
            });
        }
    });
    return reader;
}

1 Ответ

1 голос
/ 16 июня 2020

Взгляните на PatternMatchingCompositeLineTokenizer. Здесь вы можете использовать Pattern, чтобы определить, какие записи анализируются с помощью LineTokenizer. В вашем случае у вас будет один Pattern, который идентифицирует записи с разделителями-запятыми и сопоставляет их с токенизатором, который анализирует через запятые. У вас также будет Pattern, который идентифицирует записи, разделенные вертикальными чертами, и сопоставляет их с соответствующими LineTokenizer. Это будет выглядеть примерно так:

    @Bean
    public LineTokenizer compositeLineTokenizer() throws Exception {
        DelimitedLineTokenizer commaTokenizer = new DelimitedLineTokenizer();

        commaTokenizer.setNames("a", "b", "c");
        commaTokenizer.setDelimiter(",");
        commaTokenizer.afterPropertiesSet();

        DelimitedLineTokenizer pipeTokenizer = new DelimitedLineTokenizer();

        pipeTokenizer.setNames("a", "b", "c");
        pipeTokenizer.setDelimiter("|");

        pipeTokenizer.afterPropertiesSet();

        // I have not tested the patterns here so they may need to be adjusted
        Map<String, LineTokenizer> tokenizers = new HashMap<>(2);
        tokenizers.put("*,*", commaTokenizer);
        tokenizers.put("*|*", pipeTokenizer);

        PatternMatchingCompositeLineTokenizer lineTokenizer = new PatternMatchingCompositeLineTokenizer();

        lineTokenizer.setTokenizers(tokenizers);

        return lineTokenizer;
    }
...