我想要做的是跟踪删除的文件并在此周围应用某些逻辑(获取id并更新实体)。我发现我们可以在通道适配器中传递监视事件列表,包括
FileReadingMessageSource.WatchEventType.DELETE
但是当我从文件夹中删除文件时,我没有看到任何事件已触发且变压器从未被应用
@Bean
public IntegrationFlow integrationFlow(FileToMovieTransformer fileToMovieTransformer) {
return this.integrationFlowBuilder()
.transform(fileToMovieTransformer)
.channel(movieHandlerChannel())
.get();
}
private IntegrationFlowBuilder integrationFlowBuilder() {
return IntegrationFlows.from(
Files.inboundAdapter(new File(localFilmFolder))
.autoCreateDirectory(true)
.useWatchService(true)
.watchEvents(FileReadingMessageSource.WatchEventType.CREATE, FileReadingMessageSource.WatchEventType.DELETE)
.patternFilter("*.xml"),
e -> e.poller(Pollers.fixedDelay(10, TimeUnit.SECONDS)
));
}
答案 0 :(得分:1)
我会说你以错误的方式对待DELETE
:
/**
* Directory entry deleted.
*
* <p> When a directory is registered for this event then the {@link WatchKey}
* is queued when it is observed that an entry is deleted or renamed out of
* the directory. The event {@link WatchEvent#count count} for this event
* is always {@code 1}.
*/
public static final WatchEvent.Kind<Path> ENTRY_DELETE =
new StdWatchEventKind<Path>("ENTRY_DELETE", Path.class);
因此,已经没有任何内容可以作为消息向下游发出。我们在这里肯定会谈到FileReadingMessageSource
。但是对于DELETE
,没有什么可读的了。我错过了什么吗?
以下是我们迄今为止在文档中的内容:
ENTRY_DELETE
事件对ResettableFileListFilter
实施以及因此的文件有效 为remove()
操作提供。 这意味着(启用此事件时),AcceptOnceFileListFilter
等过滤器将删除该文件, 这意味着,如果出现具有相同名称的文件,它将通过过滤器并作为消息发送。
因此,为了实现DELETE
事件时您想要做的任何事情,您需要实施ResettableFileListFilter
并与SimplePatternFileListFilter
一起将它们合并到CompositeFileListFilter
中。
当文件被删除时,会发出DELETE
个事件,我们最终会得到如下逻辑:
if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
if (getFilter() instanceof ResettableFileListFilter) {
((ResettableFileListFilter<File>) getFilter()).remove(file);
}
提到的CompositeFileListFilter
肯定会实现此ResettableFileListFilter
,并将委托给您自己的实现。
答案 1 :(得分:1)
感谢@Artem,这是完整的代码示例,似乎对我很有用
private IntegrationFlowBuilder integrationFlowBuilder() {
final List<FileListFilter<File>> defaultFilters = new ArrayList<>(2);
defaultFilters.add(new IgnoreHiddenFileListFilter());
defaultFilters.add(new AcceptOnceFileListFilter<>());
defaultFilters.add(new SimplePatternFileListFilter("*.xml"));
defaultFilters.add(myCustomRemovalFilter);
CompositeFileListFilter fileListFilter = new CompositeFileListFilter<>(defaultFilters);
return IntegrationFlows.from(
Files.inboundAdapter(new File(localFilmFolder))
.autoCreateDirectory(true)
.filter(fileListFilter)
.useWatchService(true)
.watchEvents(FileReadingMessageSource.WatchEventType.CREATE, FileReadingMessageSource.WatchEventType.DELETE),
e -> e.poller(Pollers.fixedDelay(10, TimeUnit.SECONDS)
));
}
,过滤器看起来像
@Component
public class MyCustomRemovalFilter implements ResettableFileListFilter<File> {
private static final Logger LOGGER = LogManager.getLogger(MyCustomRemovalFilter.class);
@Override
public boolean remove(File xmlFile) {
if (xmlFile == null) {
return true;
}
// TODO you own on removal logic
}
@Override
public List<File> filterFiles(File[] files) {
if (files == null || files.length == 0) {
return Collections.emptyList();
}
return Arrays.asList(files);
}
}