2016-09-14 59 views
2

我对Spring非常陌生,甚至更多 - 所以对于Spring Integration来说,如果这是一个非常基本的问题,请道歉。什么是简单文件复制的适当Java配置

我想构建一个非常基本的日志文件处理器来学习绳索。非常类似于:example

我也想使用java配置方法,并且我一直遵循的大多数示例都是由XML驱动的,而且我很难进行翻译。

最终,我想循环查询日志文件的源目录并使用持久性存储来跟踪发现的内容。

然后,将要处理的文件复制到处理文件夹,然后启动弹簧批处理作业来处理文件的内容。

当一切都完成时,处理的文件可以从处理位置删除。

我似乎无法找出正确的方法来连接(使用SpEL的通用java配置)流。另外,我仍然不确定合适的作品应该是什么。

同样的东西沿着这些基本的高层次线路的文件移动:

file:inbound-channel-adapter -> channel -> file:outbound-adapter 

basic sample

这里是我迄今为止

编辑

我已经用Artem的解决方案进行了更新。我的源文件现在已正确复制到目标位置。谢谢Artem!

最终我仍然面临同样的问题。要被扫描的文件被立即找到(并且立即填充metadata-store.properties文件),但文件被缓慢地复制到目标文件夹。如果发生崩溃,任何尚未复制到目标文件夹的源文件将基本上“丢失”。也许我需要查看其他形式的持久性存储,如自定义的jdbcfilter。

@Value("${logProcessor.filenamePattern}") 
private String filenamePattern; 

@Value("${logProcessor.sourceDirectory}") 
private String sourceDirectory; 

@Value("${logProcessor.processingDirectory}") 
private String processingDirectory; 

@Bean 
@InboundChannelAdapter(channel = "sourceFileChannel", poller = @Poller(fixedRate = "5000")) 
public MessageSource<File> sourceFiles() { 

     CompositeFileListFilter<File> filters = new CompositeFileListFilter<>(); 
     filters.addFilter(new SimplePatternFileListFilter(filenamePattern)); 
     filters.addFilter(persistentFilter()); 

     FileReadingMessageSource source = new FileReadingMessageSource(); 
     source.setAutoCreateDirectory(true); 
     source.setDirectory(new File(sourceDirectory)); 
     source.setFilter(filters); 
     source.setUseWatchService(true); 

     return source; 
    } 

@Bean 
@InboundChannelAdapter(channel = "processingFileChannel", poller = @Poller(fixedRate = "5000")) 
    public MessageSource<File> processingFiles() { 

     CompositeFileListFilter<File> filters = new CompositeFileListFilter<>(); 
     filters.addFilter(new SimplePatternFileListFilter(filenamePattern)); 

     FileReadingMessageSource source = new FileReadingMessageSource(); 
     source.setAutoCreateDirectory(true); 
     source.setDirectory(new File(processingDirectory)); 
     source.setFilter(filters); 

     return source; 
    } 

@Bean 
@ServiceActivator(inputChannel = "sourceFileChannel") 
public MessageHandler fileOutboundChannelAdapter() { 
    FileWritingMessageHandler adapter = new FileWritingMessageHandler(new File(processingDirectory)); 
    adapter.setDeleteSourceFiles(false); 
    adapter.setAutoCreateDirectory(true); 
    adapter.setExpectReply(false); 
    return adapter; 
} 


    @Bean 
    public MessageChannel sourceFileChannel() { 
     return new DirectChannel(); 
    } 

    @Bean 
    public MessageChannel processingFileChannel() { 
     return new DirectChannel(); 
    } 

    @Bean 
    public DefaultDirectoryScanner defaultDirectoryScanner() { 
     return new DefaultDirectoryScanner(); 
    } 

    @Bean 
    public FileSystemPersistentAcceptOnceFileListFilter persistentFilter() { 
     FileSystemPersistentAcceptOnceFileListFilter fileSystemPersistentAcceptOnceFileListFilter = new FileSystemPersistentAcceptOnceFileListFilter(metadataStore(), ""); 
     fileSystemPersistentAcceptOnceFileListFilter.setFlushOnUpdate(true); 
     return fileSystemPersistentAcceptOnceFileListFilter; 
    } 

    @Bean 
    public PropertiesPersistingMetadataStore metadataStore(){ 
     PropertiesPersistingMetadataStore metadataStore = new PropertiesPersistingMetadataStore(); 
     metadataStore.setBaseDirectory("C:\\root\\code\\logProcessor"); 
     return metadataStore; 
    } 

回答

1

您的配置目前为止还不错。

有这样一个复杂的任务,我不知道如何帮助你。

你应该问更具体的问题。我们无法为您写出解决方案。

不确定为什么你需要将文件从一个目录复制到另一个目录,如果你只需从源目录轮询它们,存储在metadataStore并开始文件处理。

所以,我在你的配置中看到一个小问题。 FileWritingMessageHandler将结果发送到processingFileChannel,第二个FileReadingMessageSource完成相同的操作。我不确定这是你的意图。以防万一,以引起您的注意。

您可能还需要了解关于FileSplitter,它可让您逐行处理文件。

你也说processingDirectory,但你使用tmpDirFileWritingMessageHandler,我猜,这是假设你的复制逻辑。

让我们一步步完成任务吧!然后你弄清楚什么,在哪里以及如何使用!

编辑

如果你只需要复制文件到processingDirectory没有任何答复,你应该做单向适配器:

@Bean 
@ServiceActivator(inputChannel = "sourceFileChannel") 
public MessageHandler fileOutboundChannelAdapter() { 
    FileWritingMessageHandler adapter = new FileWritingMessageHandler(new File(processingDirectory)); 
    adapter.setDeleteSourceFiles(true); 
    adapter.setAutoCreateDirectory(true); 
    adapter.setExpectReply(false); 
    return adapter; 
} 

然后你@InboundChannelAdapter(channel = "processingFileChannel"好拿起文件进行处理。

不确定你需要DeleteSourceFiles虽然...

+0

谢谢你的回应Artem。文件复制的原因是为了避免文件已被找到但尚未处理的问题,类似于[thread](http://stackoverflow.com/questions/25756387/prevent-duplicates-across-restarts在春天集成)我会更新我的答案是更具体的,我只是混淆如何使用出站适配器。 – rcurrie

+0

请在我的答案中找到编辑。 –

+0

谢谢阿尔乔姆,这非常棒。我同意,源文件可以保留,因此adapter.setDeleteSourceFiles(false);我会将此标记为答案,谢谢!我应该开一个新的问题,因为我仍然面临同样的问题。 metadata-store.properties文件立即列出所有找到的文件,但这些文件缓慢复制到目标文件夹。因此,如果发生崩溃,仍然会有未处理的文件。这是我最终想要解决的问题。 – rcurrie

相关问题