什么是简单文件复制的正确 Java 配置 [英] What is the proper Java Config for simple file copy

查看:21
本文介绍了什么是简单文件复制的正确 Java 配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Spring 非常陌生,对 Spring Integration 更是如此,如果这是一个非常基本的问题,我深表歉意.

我想构建一个非常基本的日志文件处理器来学习绳索.与此非常相似:示例

我还想使用 java 配置方法,而且我所遵循的大多数示例都是 XML 驱动的,而且我很难进行翻译.

最终我想递归地轮询日志文件的源目录并使用持久性存储来跟踪找到的内容.

然后,将这些要处理的文件复制到一个处理文件夹中,然后启动一个spring批处理作业来处理文件的内容.

当一切完成后,可以从处理位置删除处理过的文件.

我似乎无法找出连接(使用 SpEL 的通用 java 配置)流程的正确方法.此外,我仍然非常不确定合适的部分应该是什么.

关于文件移动的这些基本的、高级别的内容:

file:inbound-channel-adapter ->频道 ->文件:出站适配器

基础示例

这是我目前所拥有的

编辑

我已经更新了 Artem 的解决方案.我的源文件现在已正确复制到目标位置.谢谢阿尔乔姆!

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

@Value("${logProcessor.filenamePattern}")私人字符串文件名模式;@Value("${logProcessor.sourceDirectory}")私有字符串源目录;@Value("${logProcessor.processingDirectory}")私有字符串处理目录;@豆@InboundChannelAdapter(channel = "sourceFileChannel", poller = @Poller(fixedRate = "5000"))公共消息源<文件>源文件(){CompositeFileListFilter<文件>过滤器 = 新的 CompositeFileListFilter<>();filters.addFilter(new SimplePatternFileListFilter(filenamePattern));过滤器.addFilter(persistentFilter());FileReadingMessageSource source = new FileReadingMessageSource();source.setAutoCreateDirectory(true);source.setDirectory(新文件(sourceDirectory));source.setFilter(过滤器);source.setUseWatchService(true);返回源;}@豆@InboundChannelAdapter(channel = "processingFileChannel", poller = @Poller(fixedRate = "5000"))公共消息源<文件>处理文件(){CompositeFileListFilter<文件>过滤器 = 新的 CompositeFileListFilter<>();filters.addFilter(new SimplePatternFileListFilter(filenamePattern));FileReadingMessageSource source = new FileReadingMessageSource();source.setAutoCreateDirectory(true);source.setDirectory(新文件(处理目录));source.setFilter(过滤器);返回源;}@豆@ServiceActivator(inputChannel = "sourceFileChannel")public MessageHandler fileOutboundChannelAdapter() {FileWritingMessageHandler 适配器 = new FileWritingMessageHandler(new File(processingDirectory));适配器.setDeleteSourceFiles(false);适配器.setAutoCreateDirectory(true);适配器.setExpectReply(false);返回适配器;}@豆公共 MessageChannel sourceFileChannel() {返回新的 DirectChannel();}@豆public MessageChannel processingFileChannel() {返回新的 DirectChannel();}@豆公共 DefaultDirectoryScanner defaultDirectoryScanner() {返回新的 DefaultDirectoryScanner();}@豆public FileSystemPersistentAcceptOnceFileListFilter persistentFilter() {FileSystemPersistentAcceptOnceFileListFilter fileSystemPersistentAcceptOnceFileListFilter = new FileSystemPersistentAcceptOnceFileListFilter(metadataStore(), "");fileSystemPersistentAcceptOnceFileListFilter.setFlushOnUpdate(true);返回 fileSystemPersistentAcceptOnceFileListFilter;}@豆公共属性PersistingMetadataStore metadataStore(){PropertiesPersistingMetadataStore metadataStore = new PropertiesPersistingMetadataStore();metadataStore.setBaseDirectory("C:\\root\\code\\logProcessor");返回元数据存储;}

解决方案

到目前为止,您的配置很好.

面对如此复杂的任务,我不知道如何帮助您.

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

不确定为什么需要将文件从一个目录复制到另一个目录,如果您可以简单地从源目录轮询它们,将它们存储在 metadataStore 中并开始文件处理.

到目前为止,我发现您的配置中有一个小问题.FileWritingMessageHandler 将结果发送到 processingFileChannel,第二个 FileReadingMessageSource 也是如此.我不确定这是你的意图.以防万一.

您可能还需要了解 FileSplitter,让你逐行处理文件.

您还说 processingDirectory,但随后您将 tmpDir 用于 FileWritingMessageHandler,我猜它假定您的复制逻辑.

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

编辑

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

@Bean@ServiceActivator(inputChannel = "sourceFileChannel")public MessageHandler fileOutboundChannelAdapter() {FileWritingMessageHandler 适配器 = new FileWritingMessageHandler(new File(processingDirectory));适配器.setDeleteSourceFiles(true);适配器.setAutoCreateDirectory(true);适配器.setExpectReply(false);返回适配器;}

然后你的 @InboundChannelAdapter(channel = "processingFileChannel" 很适合拿起文件进行处理.

不确定您是否需要DeleteSourceFiles...

I'm extremely new to Spring, and even more-so to Spring Integration, so apologies if this is a very basic question.

I'm wanting to build a very basic log file processor to learn the ropes. Very similar to this: example

I'm also wanting to use a java config approach, and most of the examples I've been following are all XML driven and I'm having a hard time doing the translation.

Ultimately I'd like to recursively poll a source directory for log files and use a persistence store to keep track of what's been found.

Then, copy those files to be processed to a processing folder, and then kick off a spring batch job to process the contents of the file.

When everything completes the processed file can be deleted from the processing location.

I can't seem to figure out the proper way to wire up (using general java config of SpEL) the flow. Also, I'm still very unsure of what the proper pieces should be.

Again something along these basic, high-level lines for the file moving:

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

basic sample

Here is what I have so far

EDIT

I've updated with Artem's solution. My source files are now properly copied to the destination location. Thanks Artem!

Ultimately I am still facing the same problem. The files to be scanned are found immediately (and the metadata-store.properties files is populated immediately) but the files are slowly copied to the destination folder. If a crash happens, any source files that have not been copied to the destination folder will essentially be "lost". Perhaps I need to look at other forms of persistence stores, like a custom 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;
    }

解决方案

You config is good so far.

Having such a complex task, I'm not sure how to help you.

You should ask more specific question. We can't write the solution for you.

Not sure why you need to copy files from one dir to another, if you can simply poll them from the source dir, store in the metadataStore and start a file processing.

So, far I see a small problem in your config. The FileWritingMessageHandler sends results to the processingFileChannel and the same is done by the second FileReadingMessageSource. I'm not sure that it is your intention. Just in case to pay your attention.

You might also need to know about FileSplitter, which lets you to process file line by line.

Also you say processingDirectory, but then you use tmpDir for the FileWritingMessageHandler, which, I guess, assumes your copy logic.

Let's do the task step by step! And then you figure out what, where and how to use!

EDIT

If you need just copy file to the processingDirectory without any reply, you should do one-way adapter:

@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;
}

And then that your @InboundChannelAdapter(channel = "processingFileChannel" is good to pick up files for processing.

Not sure that you need to DeleteSourceFiles though...

这篇关于什么是简单文件复制的正确 Java 配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆