我的WatchService有问题。以下是我的代码片段:
public void watch(){
//define a folder root
Path myDir = Paths.get(rootDir+"InputFiles/"+dirName+"/request");
try {
WatchService watcher = myDir.getFileSystem().newWatchService();
myDir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
WatchKey watckKey = watcher.take();
List<WatchEvent<?>> events = watckKey.pollEvents();
for (WatchEvent event : events) {
//stuff
}
}catch(Exception e){}
watckKey.reset();
}
*首先,要知道watch()是在一个无限循环中调用的。
问题是,当一次创建多个文件时,会丢失一些事件。例如,如果我将三个文件复制粘贴到"…/request"文件夹中,只有一个被捕获,其他文件则保持原样,不会触发OVERFLOW事件。在一些不同的计算机和操作系统中,它最多可以访问两个文件,但如果其中一个尝试了3个或更多,其余的文件仍然没有受到影响。
不过我找到了一个变通办法,但我认为这不是最好的做法。这就是流程:
该过程在处开始,然后停止
WatchKey watckKey = watcher.take();
如预期,(根据处理事件)。然后,我把3个文件放在"请求"文件夹中,这样,在上恢复处理
List<WatchEvent<?>> events = watckKey.pollEvents();
问题就在这里。这条线似乎过得太快了,以至于两个CREATED事件留下来并丢失了,只有一个被拿走了。解决方法是在这一行的正上方添加一行,如下所示:
Thread.sleep(1000);
List<WatchEvent<?>> events = watckKey.pollEvents();
这似乎是一个解决方案,至少对于三个或多个同时存在的文件来说是这样,但它根本不可扩展。最后,我想知道这个问题是否有更好的解决方案。仅供参考,我正在运行Win 7 64
提前感谢!
请确保重置您的watchKey。前面提到的一些答案没有,这也可以解释掉的事件。我推荐Oracle官方文档中给出的示例:https://docs.oracle.com/javase/tutorial/essential/io/notification.html
请注意,即使使用正确,文件服务的可靠性也在很大程度上取决于底层操作系统。一般来说,它应该被认为是一种尽最大努力的机制,不能提供100%的保证。
如果在无限循环中调用watch,那么您正在创建无限次的watch服务,因此可能会丢失事件,我建议您执行以下操作,调用您的方法watchservice一次:
public void watchservice()
{
Thread fileWatcher = new Thread(() ->
{
Path path = Paths.get(rootDir+"InputFiles/"+dirName+"/request");
Path dataDir = Paths.get(path);
try
{
WatchService watcher = dataDir.getFileSystem().newWatchService();
dataDir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
while (true)
{
WatchKey watckKey;
try
{
watckKey = watcher.take();
}
catch (Exception e)
{
logger.error("watchService interupted:", e);
return;
}
List<WatchEvent<?>> events = watckKey.pollEvents();
for (WatchEvent<?> event : events)
{
logger.debug("Event Type : "+ event.kind() +" , File name found :" + event.context());
if (event.kind() != StandardWatchEventKinds.OVERFLOW)
{
// do your stuff
}
}
}
}
catch (Exception e)
{
logger.error("Error: " , e);
}
});
fileWatcher.setName("File-Watcher");
fileWatcher.start();
fileWatcher.setUncaughtExceptionHandler((Thread t, Throwable throwable) ->
{
logger.error("Error ocurred in Thread " + t, throwable);
});
}