首页 > 解决方案 > Spring批处理 - 获取有关目录中文件的信息

问题描述

所以我第一次玩弄 Spring Batch 并试图了解除了处理 CSV 文件之外如何做其他事情。

例如,尝试读取目录中的每个音乐文件时,我有以下代码,但我不确定如何处理该Delegate部分。

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Bean
    public MusicItemProcessor processor() {
        return new MusicItemProcessor();
    }

    @Bean
    public Job readFiles() {
        return jobBuilderFactory.get("readFiles").incrementer(new RunIdIncrementer()).
                flow(step1()).end().build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1").<String, String>chunk(10)
                .reader(reader())
                .processor(processor()).build();
    }

    @Bean
    public ItemReader<String> reader() {
        Resource[] resources = null;
        ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
        try {
            resources = patternResolver.getResources("file:/music/*.flac");
        } catch (IOException e) {
            e.printStackTrace();
        }

        MultiResourceItemReader<String> reader = new MultiResourceItemReader<>();
        reader.setResources(resources);
        reader.setDelegate(new FlatFileItemReader<>()); // ??

        return reader;
    }

}

目前我可以看到资源有一个音乐文件列表,但是查看我返回的堆栈跟踪,在我看来它new FlatFileItemReader<>()正在尝试读取文件的实际内容(我会想在某个时候这样做,只是现在不行)。

目前我只想要关于文件的信息(绝对路径、大小、文件名等),而不是里面的内容。

我完全错了吗?还是我只需要配置一些不同的东西?

任何不仅仅处理 CSV 行的代码示例也很棒

标签: springspring-batch

解决方案


在搜索了互联网之后,我设法收集了一些我认为可行的东西......欢迎提供一些反馈。

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Bean
    public VideoItemProcessor processor() {
        return new VideoItemProcessor();
    }

    @Bean
    public Job readFiles() {
        return jobBuilderFactory.get("readFiles")
                .start(step())
                .build();
    }

    @Bean
    public Step step() {
        try {
            return stepBuilderFactory.get("step").<File, Video>chunk(500)
                    .reader(directoryItemReader())
                    .processor(processor())
                    .build();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Bean
    public DirectoryItemReader directoryItemReader() throws IOException {
        return new DirectoryItemReader("file:/media/media/Music/**/*.flac");
    }
}

让我坚持为文件创建自定义阅读器的部分。如果其他人遇到这种情况,我就是这样做的。我敢肯定有更好的方法,但这对我有用

public class DirectoryItemReader implements ItemReader<File>, InitializingBean {
    private final String directoryPath;

    private final List<File> foundFiles = Collections.synchronizedList(new ArrayList<>());

    public DirectoryItemReader(final String directoryPath) {
        this.directoryPath = directoryPath;
    }

    @Override
    public File read() {
        if (!foundFiles.isEmpty()) {
            return foundFiles.remove(0);
        }

        synchronized (foundFiles) {
            final Iterator files = foundFiles.iterator();

            if (files.hasNext()) {
                return foundFiles.remove(0);
            }
        }

        return null;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        for (final Resource file : getFiles()) {
            this.foundFiles.add(file.getFile());
        }
    }

    private Resource[] getFiles() throws IOException {
        ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
        return patternResolver.getResources(directoryPath);
    }
}

您唯一需要做的就是实现您自己的处理器。我在这个例子中使用了视频,所以我有一个视频处理器

@Slf4j
public class VideoItemProcessor implements ItemProcessor<File, Video> {

    @Override
    public Video process(final File item) throws Exception {
        Video video = Video.builder()
                .filename(item.getAbsoluteFile().getName())
                .absolutePath(item.getAbsolutePath())
                .fileSize(item.getTotalSpace())
                .build();

        log.info("Created {}", video);

        return video;
    }
}

推荐阅读