2015-04-22 1 views
5

У меня проблема с WatchService. Вот отрывок из моего кода: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(); 

} 

* Прежде всего, знайте, что часы() вызывается внутри бесконечного цикла.

Проблема в том, что при создании нескольких файлов за раз некоторые события отсутствуют. Например, если я скопирую-вставляю три файла в папку «.../запрос», только один попадает в ловушку, остальные остаются, как будто ничего не происходит, ни одно событие OVERFLOW не запускается. В некоторых разных компьютерах и ОС он достигает двух файлов, но если вы пытаетесь 3 или более, остальные остаются нетронутыми.

Я нашел обходное решение, но я не думаю, что это лучшая практика. Это поток:

запускается процесс, а затем останавливается на

WatchKey watckKey = watcher.take(); 

, как и ожидалось, (в соответствии с Processing events). Затем я удаляю 3 файла вместе в папку «запрос», таким образом, процесс возобновляется на

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

Проблема здесь. Похоже, что поток проходит так быстро через эту строку, что два события CREATED остаются позади и теряются, только один берется. Чтобы обойти эту проблему, чтобы добавить дополнительную строку прямо над этим, как это:

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

Это, как представляется, решение, по крайней мере, в течение трех и более нескольких одновременных файлов, но это не масштабируется вообще. Итак, в заключение я хотел бы знать, есть ли лучшее решение для этой проблемы. FYI, я запускаю Win 7 64

Большое спасибо!

ответ

1

Если часы называется внутри бесконечного цикла, то вы создаете часы службы бесконечного не раз, следовательно, возможность потери события, я бы предложил сделать следующее, позвоните своему методу 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); 
    }); 
} 
+0

В некоторых point in my encoding Я сделал это, я взял создание сервисной службы из бесконечного цикла. Я точно не помню, почему, и я не пробовал эту ситуацию снова. Обходной путь все еще существует – McCoy