You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Spring Integration SMB入站适配器丢弃过期远程文件

问题

我的应用需要定期从远程文件服务器下载文件,基于Spring Integration SMB的实现可正常运行(代码如下)。但受基础架构和运行时条件限制,应用无法控制远程服务器及本地目录的文件删除时机,可能导致文件重复下载,浪费网络与存储资源。

短期可通过AcceptOnceFileListFilter解决该问题,但出于技术简洁性考虑,我不想使用元数据存储,因此该过滤器无法在系统重启后保留状态,长期存在隐患。

我的业务场景允许仅轮询未达到指定时长(如数天)的远程文件(基于最后修改时间),即需要类似反向的SmbLastModifiedFileListFilter(该过滤器会丢弃过新的文件)。是否有简单的实现方式?若能结合现有SmbLastModifiedFileListFilter实现时间区间过滤则更佳。

@Bean
public IntegrationFlow integrationFlow() {
    return IntegrationFlow.from(
                    Smb.inboundAdapter(smbSessionFactory())
                            .remoteDirectory("/myRemoteDirectory")
                            .filter(fileListFilter())
                            .localDirectory(new File("/myLocalDirectory"))
                            .autoCreateLocalDirectory(true)
                            .preserveTimestamp(true),
                    e -> e.poller(Pollers.fixedDelay(60000).maxMessagesPerPoll(-1))
            )
            .channel(new NullChannel()) // Discard payload
            .get();
}

@Bean
public CompositeFileListFilter<SmbFile> fileListFilter() {
    final var filters = new CompositeFileListFilter<SmbFile>();
    filters.addFilter(new AcceptOnceFileListFilter<>());
    filters.addFilter(new SmbRegexPatternFileListFilter(".*\\.txt"));
    filters.addFilter(new SmbLastModifiedFileListFilter(30));
    // another "reverse" SmbLastModifiedFileListFilter required here
    return filters;
}

解决方案

方式一:自定义反向的SmbLastModifiedFileListFilter

直接继承AbstractLastModifiedFileListFilter<SmbFile>,重写accept方法,保留最后修改时间距今不超过指定时长的文件(与原过滤器逻辑完全相反):

public class SmbNewerThanLastModifiedFileListFilter extends AbstractLastModifiedFileListFilter<SmbFile> {

    public SmbNewerThanLastModifiedFileListFilter(long age) {
        super(age);
    }

    @Override
    protected long getLastModified(SmbFile file) {
        return file.getLastModified();
    }

    @Override
    public boolean accept(SmbFile file) {
        long cutoff = System.currentTimeMillis() - this.getAge();
        // 仅保留最后修改时间晚于cutoff的文件(即文件未超过指定时长)
        return file.getLastModified() >= cutoff;
    }
}

方式二:组合过滤器实现时间区间过滤

如果需要同时过滤出**最后修改时间在[X天前, Y分钟内]**的文件,直接组合原SmbLastModifiedFileListFilter和自定义过滤器即可,既避免下载过旧文件,也避免下载未完全写入的新文件:

@Bean
public CompositeFileListFilter<SmbFile> fileListFilter() {
    final var filters = new CompositeFileListFilter<SmbFile>();
    filters.addFilter(new SmbRegexPatternFileListFilter(".*\\.txt"));
    // 保留最后修改时间不超过7天的文件(换算为毫秒:7*24*60*60*1000=604800000)
    filters.addFilter(new SmbNewerThanLastModifiedFileListFilter(604800000));
    // 保留最后修改时间超过30分钟的文件,避免下载未写完的文件
    filters.addFilter(new SmbLastModifiedFileListFilter(30));
    return filters;
}

关键说明

  • 自定义过滤器完全基于文件本身的最后修改时间判断,无需依赖任何元数据存储,重启后状态不受影响,符合技术简洁性要求。
  • 可以直接去掉原AcceptOnceFileListFilter,因为时间过滤逻辑已经能避免重复下载(只要远程文件的最后修改时间不被篡改)。

内容的提问来源于stack exchange,提问作者mrnst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 04:11:18