Java 7 WatchService:在处理程序中更改事件源时避免无限循环事件

4
基本上,我正在使用最新的Java 7 WatchService来监视目录。
我有一系列的处理程序监听目录发出的每个IO事件。
问题是其中一些处理程序需要以某种方式更改这些IO事件(==文件)的原因。例如,如果有人将文件放入受监视的文件夹中,则其中一个处理程序可能会更改其扩展名,在文件名中添加一些内容或其他操作。
这些操作显然会触发新的IO事件,并且上述处理程序会接收到它们。然后他们再次进行更改。这显然会导致无限循环...
Java是否提供了处理这种情况的方法?如果没有,你会如何处理?
基本上,我想在事件不是由这些处理程序的操作引起时才运行我的事件处理程序。
更新:至于解决方案,我宁愿只在主事件路由器的代码中进行更改,而不必在我编写的每个处理程序中担心这个问题(“处理程序仅在之前未进行更改时进行更改”)。

我怀疑你需要根据之前的操作在处理程序中跟踪要忽略哪些事件。如果Mark Elliot的答案可行,最简单的方法就是使用他的方法。 - jontro
2个回答

4

只有没有基本案例才会导致无限循环。

假设人们将文件放在扩展名为“ .bar”的目录中,并且您想要扩展名为“ .foo”,那么您的处理程序仅在当前扩展名为“ .bar”时才进行更改。

即使您的处理程序仍会收到新的 <file>.foo 事件,您也可以将其丢弃,停止“无限”事件传播。


这个问题仍然有价值。假设您想对放置在监视目录中的所有文件执行操作,然后执行可能不容易检测到的操作。因此,您只想对外部调用者进行的修改采取行动。 - jontro
@jontro:关键是对于那些你正在自动生成事件的情况,而且那个生成可能会导致无限循环,你必须有一个基本情况,就像递归一样。 - Mark Elliot
是的,当然有这个问题,但就像jontro所说的那样——只有在有外部调用者时才采取行动似乎是一个合理和可能的情况。我宁愿只在主事件路由器的代码中进行更改,而不必担心我编写的每个处理程序中的这个问题。 - Paweł Bara
1
@PawełBara,如果其他人修改了文件,然后再次修改该文件,则那个会生成事件,这正是我所描述的。您需要一个基本情况。而且只有在您知道什么会导致本地事件触发时,才能合理地存在该基本情况,例如在处理程序中。 - Mark Elliot

0
我建议每次代码处理事件触发新事件时使用新线程。在事件处理程序中检查更改的文件是否需要重命名,如果是,则启动执行重命名的新线程,否则从事件返回。 这样做可以避免无限循环,因为事件处理代码总会以某种方式退出。

一个新的线程?线程会占用大量系统内存,因此特别建议不要使用比所需更多的线程。认真点,不要这样做,它也无法解决问题。 - ThePyroEagle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接