6

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() が無限ループ内で呼び出されることを知っておいてください。

問題は、一度に複数のファイルを作成すると、一部のイベントが欠落することです。たとえば、3 つのファイルを「.../request」フォルダーにコピー アンド ペーストすると、1 つだけがキャッチされ、他のファイルは何も起こらなかったかのように残り、OVERFLOW イベントもトリガーされません。一部の異なるコンピューターと OS では、最大 2 つのファイルに到達しますが、1 つが 3 つ以上を試行しても、残りはそのままです。

回避策を見つけましたが、それがベストプラクティスだとは思いません。フローは次のとおりです。

プロセスが開始され、次に停止します

WatchKey watckKey = watcher.take();

予想通り (処理中のイベントに従って)。次に、「request」フォルダーに 3 つのファイルをまとめてドロップします。

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

問題はここです。スレッドがこの行を非常に速く通過しているように見えるため、2 つの CREATED イベントが遅れて失われ、1 つだけが取得されます。回避策は、次のように、この行のすぐ上に余分な行を追加することでした:

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

これは、少なくとも 3 つ以上の同時ファイルに対する解決策のようですが、スケーラブルではありません。結論として、この問題に対するより良い解決策があるかどうかを知りたいと思います。参考までに、私はWin 7 64を実行しています

よろしくお願いします!

4

2 に答える 2

2

時計が無限ループ内で呼び出された場合、監視サービスを無限に作成しているため、イベントが失われる可能性があります。次のことをお勧めします。メソッドwatchserviceを1回呼び出します。

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);
    });
}
于 2018-01-31T06:27:20.403 に答える