【发布时间】:2015-10-20 14:04:22
【问题描述】:
使用 Spring Integration Java DSL,我构建了一个流程,在该流程中我与 FileSplitter 同步处理文件。在将File 中的每一行转换为Message 以进行后续处理后,我已经能够使用AbstractFilePayloadTransformer 上的setDeleteFiles 标志来删除文件,如下所示:
@Bean
protected IntegrationFlow s3ChannelFlow() {
// do not exhaust filesystem w/ files downloaded from S3
FileToInputStreamTransformer transformer = new FileToInputStreamTransformer();
transformer.setDeleteFiles(true);
// @see http://docs.spring.io/spring-integration/reference/html/files.html#file-reading
// @formatter:off
return IntegrationFlows
.from(s3Channel())
.channel(StatsUtil.createRunStatsChannel(runStatsRepository))
.transform(transformer)
.split(new FileSplitter())
.transform(new JsonToObjectViaTypeHeaderTransformer(new Jackson2JsonObjectMapper(objectMapper), typeSupport))
.publishSubscribeChannel(p -> p.subscribe(persistenceSubFlow()))
.get();
// @formatter:on
}
这很好用,但速度很慢。所以我尝试在上面的.split 之后添加一个ExecutorChannel,如下所示:
.channel(c -> c.executor(Executors.newFixedThreadPool(10)))
但是前面提到的删除标志不允许流程在完全读取文件之前完成成功删除文件。
如果我删除该标志,我可能会耗尽从 S3 同步文件的本地文件系统。
我可以在上面介绍什么 a) 完全处理每个文件 b) 完成后从本地文件系统中删除文件? 换句话说,有没有办法准确知道文件何时完全处理(当它的行已通过池中的线程异步处理时)?
如果你好奇,这里是我对 FileToInputStreamTransformer 的暗示:
public class FileToInputStreamTransformer extends AbstractFilePayloadTransformer<InputStream> {
private static final int BUFFER_SIZE = 64 * 1024; // 64 kB
@Override
// @see http://java-performance.info/java-io-bufferedinputstream-and-java-util-zip-gzipinputstream/
protected InputStream transformFile(File payload) throws Exception {
return new GZIPInputStream(new FileInputStream(payload), BUFFER_SIZE);
}
}
更新
那么,下游流中的某些东西是如何知道要请求什么的呢?
顺便说一句,如果我正确地遵循了你的建议,当我用上面的new FileSplitter(true, true) 更新.split 时,我得到了
【问题讨论】:
标签: java file spring-integration dsl splitter