WatchService: Missed and Unhandled Events

I have a problem with WatchService. Here is a snippet of my code:

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(); } 

* First of all, be aware that watch () is called inside an infinite loop.

The problem is that when creating multiple files at a time, some events are missing. For example, if I copy-paste three files into the "... / request" folder, only one falls into the trap, the rest remain as if nothing was happening, no OVERFLOW event was fired. On some different computers and OS, it reaches two files, but if you try 3 or more, the rest remain untouched.

I found a workaround, but I don't think this is the best practice. This is the thread:

The process begins and then stops at

 WatchKey watckKey = watcher.take(); 

as expected (according to Event Handling ). Then I delete 3 files together in the "request" folder, so the process resumes with

 List<WatchEvent<?>> events = watckKey.pollEvents(); 

The problem is here. It seems that the stream goes so fast through this line that two CREATED events are left behind and lost, only one is taken. The workaround was to add an extra line directly above this, for example:

 Thread.sleep(1000); List<WatchEvent<?>> events = watckKey.pollEvents(); 

This seems to be a solution for at least three and several simultaneous files, but it does not scale at all. Therefore, in conclusion, I would like to know if there is a better solution to this problem. FYI, I am running Win 7 64

Many thanks!

+5
source share
1 answer

If the clock is called inside an infinite loop, then you create an infinite number of hours, therefore, the ability to play events, I would suggest doing the following: Call your watchservice method once:

 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); }); } 
+1
source

All Articles