远程持久化文件列表过滤器
入站和流式入站远程文件通道适配器(FTP、SFTP 及其他技术)默认配置了 AbstractPersistentAcceptOnceFileListFilter 的相应实现,并使用内存中的 MetadataStore 进行配置。要在集群中运行,可以将这些过滤器替换为使用共享 MetadataStore 的过滤器(更多信息请参阅 元数据存储)。这些过滤器用于防止多次获取同一文件(除非其修改时间发生变化)。从版本 5.2 开始,文件在获取之前会立即添加到过滤器中(如果获取失败,则会撤销此操作)。
从版本7.0开始,所有 AbstractPersistentAcceptOnceFileListFilter 实现都使用"长文件名"(获取目录加上简单文件名)作为元数据条目的键。在此之前,当同一个过滤器用于不同目录但文件名相同时,仅使用文件名可能导致元数据覆盖问题。例如,RotatingServerAdvice 可能会根据时间戳切换到不同目录,但根据业务逻辑,文件会以相同的名称放置在这些目录中。如果 directory1 和 directory2 都包含一个 someFile,它们的元数据将分别以 directory1/someFile 和 directory2/someFile 存储。这是在过滤器的 prefix 选项被设置为空字符串的情况下,否则这样的前缀会被添加到最终键中。
如果发生灾难性故障(例如断电),当前正在获取的文件可能会保留在过滤器中,并且在重启应用程序时不会被重新获取。在这种情况下,您需要手动从 MetadataStore 中删除此文件。
在之前的版本中,文件在获取之前就已经被过滤了,这意味着在发生灾难性故障后,可能会有多个文件处于这种状态。
为了支持这一新行为,FileListFilter 中新增了两个方法。
boolean accept(F file);
boolean supportsSingleFileFiltering();
如果过滤器在 supportsSingleFileFiltering 中返回 true,则必须实现 accept() 方法。
如果远程过滤器不支持单文件过滤(例如 AbstractMarkerFilePresentFileListFilter),适配器将恢复为之前的行为。
如果使用了多个过滤器(一个 CompositeFileListFilter 或 ChainFileListFilter),那么所有委托过滤器都必须支持单文件过滤,才能使组合过滤器支持该功能。
持久化文件列表过滤器现在新增了一个布尔属性 forRecursion。将此属性设置为 true 时,也会同时设置 alwaysAcceptDirectories,这意味着出站网关(ls 和 mget)上的递归操作现在每次都会遍历完整的目录树。这是为了解决深层目录树中的变更无法被检测到的问题。此外,forRecursion=true 会导致使用文件的完整路径作为元数据存储的键;这解决了当同名文件在不同目录中多次出现时过滤器无法正常工作的问题。重要提示:这意味着对于顶级目录下的文件,持久化元数据存储中现有的键将无法被找到。因此,该属性默认值为 false;这可能会在未来的版本中发生改变。