Spring Integration:如何从FTP服务器仅下载新文件或更新文件?
解决Spring Integration FTP客户端避免重复下载大文件的问题
看起来你已经搭好了基础的FTP会话工厂配置,针对大文件不想重复下载的需求,我们可以通过调整FtpInboundFileSynchronizer和消息源的配置,结合文件跟踪过滤器来实现。
先把你给出的现有配置整理成规范的代码块:
@Bean open fun ftpSessionFactory() = DefaultFtpSessionFactory().apply { setHost(env.getProperty(FTP_HOST)) setPort(env.getProperty(FTP_PORT)!!.toInt()) setUsername(env.getProperty(FTP_USER)) setPassword(env.getProperty(FTP_PASSWORD)) }
核心解决方案:添加文件跟踪过滤器
要避免重复下载,关键是让客户端记住已经处理过的文件。这里推荐使用持久化的文件过滤器,即使服务重启也不会丢失已下载记录,非常适合大文件场景。完整配置示例如下:
@Bean open fun ftpInboundFileSynchronizer(sessionFactory: SessionFactory<FTPFile>) = FtpInboundFileSynchronizer(sessionFactory).apply { // 设置远程FTP服务器的目标目录 setRemoteDirectory(env.getProperty(FTP_REMOTE_DIR)) // 设置本地存储下载文件的目录 setLocalDirectory(File(env.getProperty(FTP_LOCAL_DIR))) // 大文件建议保留远程源文件,所以设为false setDeleteRemoteFiles(false) } @Bean open fun ftpMessageSource(synchronizer: FtpInboundFileSynchronizer) = FtpInboundFileSynchronizingMessageSource(synchronizer).apply { // 持久化过滤器:记录已下载文件,重启不重复下载 val persistentFilter = PersistentAcceptOnceFileListFilter( SimpleMetadataStore(), "ftp-download-tracker-" ) // 可选:添加文件后缀过滤,比如只下载大文件常用的.csv/.zip等 persistentFilter.setFilter(FtpSimplePatternFileListFilter("*.zip")) setFilter(persistentFilter) // 大文件场景建议每次只同步1个文件,避免资源过载 setMaxFetchSize(1) }
关键配置说明
PersistentAcceptOnceFileListFilter: 这个过滤器会把已下载文件的元数据存在MetadataStore里,默认用内存实现SimpleMetadataStore。如果需要更可靠的持久化(比如集群场景),可以替换成RedisMetadataStore或者JdbcMetadataStore。setMaxFetchSize: 针对大文件,限制每次同步的文件数量,避免同时下载多个大文件占用过多内存和带宽。setDeleteRemoteFiles: 建议保持false,保留远程服务器上的源文件,既方便后续校验,也避免误删重要数据。
如果你的业务需要更复杂的逻辑(比如下载后给远程文件重命名标记已处理),还可以自定义FileListFilter或者扩展FtpInboundFileSynchronizer的同步逻辑。
内容的提问来源于stack exchange,提问作者Peter Tsilko
相关产品推荐
相关产品推荐

