Java NIO WatchService

huangapple go评论68阅读模式
英文:

Java NIO WatchService

问题

我有一个Java项目,我们需要保持监听某个路径,以便检测是否有任何新的XML文件,如果是真的,我们需要通过几个其他规则来处理它。

WatchService非常适合发现是否有新文件需要处理,但是我无法管理它,以便能够读取文件,它只会将文件名返回给我,从事件中。

是否有办法在WatchService中实现这一点?如果没有,还有其他建议吗?

谢谢。

英文:

I have Java project that we need to keep listening some path to detect if there is any new XML file and if true, we need to process it through few other rules.

The WatchService is doing very well to discover if I have a new file there to be processed, but I wasnt able to manage it so I could read the file, I just gives me back the file name, from the event.

Is there any way to that with WatchService? If not, whats another sugestion to reach?

Thanks.

答案1

得分: 1

当然,你可以轻松地实现这个:

  1. 创建监视服务:
WatchService watchService = null;

try {
    watchService = FileSystems.getDefault().newWatchService();
    Path path = get(pathToSee);
    path.register(watchService, new WatchEvent.Kind[]{ENTRY_MODIFY, ENTRY_CREATE}, SensitivityWatchEventModifier.HIGH);
    watchEvent(watchService, path);
    log.info("监视服务已创建!");
} catch (IOException e) {
    log.error("在尝试创建监视服务时抛出异常:", e);
}

注意:如果有大量文件需要添加,你可以使用:

SensitivityWatchEventModifier.HIGH

来增加敏感度。

  1. 监视目录是否有变化:
WatchKey key;
while (true) {
    try {
        if ((key = watchService.take()) == null) break;

        for (WatchEvent<?> event : key.pollEvents()) {
            log.info("事件类型:" + event.kind()
                    + "。受影响的文件:" + event.context() + "。");

            String fileName = event.context().toString();
            File directory = path.toFile();
            yourService.readContent(directory, fileName);
        }
        key.reset();
    } catch (InterruptedException | IOException e) {
        log.error("尝试执行 watchEvent() 时出现中断异常:" + e);
    }
}
  1. 最后,你可以根据这些信息执行你想要的操作:
try (BufferedReader br = new BufferedReader(new FileReader(directory + "/" + fileName))) {
    String strLine;
    while ((strLine = br.readLine()) != null) {
        // 在这里执行你想要的操作
    }
}

提示:

  1. 你可以创建一个单独的线程来执行这个任务,或者使用 Spring 的 @Async 来创建一个单独的线程来处理这些信息,以增加应用程序的并发性。

  2. 你也可以使用 Apache Commons 来实现这个功能!

例如:

public void getAll() throws Exception {
    FileAlterationObserver observer = new FileAlterationObserver(pathToSee);
    observer.addListener(new FileAlterationListenerAdaptor() {

        @SneakyThrows
        @Override
        public void onFileCreate(File file) {
            // 在这里执行文件创建时的操作
        }

        @Override
        public void onFileDelete(File file) {
            // 在这里执行文件删除时的操作
        }
    });
}
英文:

Sure, you can easely to that:

  1. Create the watch service:

     WatchService watchService = null;
    
     try {
         watchService = FileSystems.getDefault().newWatchService();
         Path path = get(pathToSee);
         path.register(watchService, new WatchEvent.Kind[]{ENTRY_MODIFY, ENTRY_CREATE}, SensitivityWatchEventModifier.HIGH);
         watchEvent(watchService, path);
         log.info(&quot;Watch Service has ben created!&quot;);
     } catch (IOException e) {
         log.error(&quot;Exception has ben throw when the service have tried to createWatchService()&quot;, e);
     }
    

Note: If you have a large amount of files to be added, you can put:

SensitivityWatchEventModifier.HIGH

To increase sensitivity.

  1. Watch if have changes in you directory:

     WatchKey key;
     while (true) {
         try {
             if ((key = watchService.take()) == null) break;
    
             for (WatchEvent&lt;?&gt; event : key.pollEvents()) {
                 log.info(&quot;Event kind:&quot; + event.kind()
                         + &quot;. File affected: &quot; + event.context() + &quot;.&quot;);
    
                 String fileName = event.context().toString();
                 File directory = path.toFile();
                 yourService.readContent(directory, fileName);
             }
             key.reset();
         } catch (InterruptedException | IOException e) {
             log.error(&quot;InterruptedException when try watchEvent()&quot; + e);
         }
     }
    
  2. And finally, you can do what you want to do with that infos:

     try (BufferedReader br = new BufferedReader(new FileReader(directory + &quot;/&quot; + fileName))) {
         String strLine;
         while ((strLine = br.readLine()) != null) {
                 }
             }
         }
     }
    

Tips:

  1. You can create a separete thread to do that, or use Spring @Async to create a separete thread to process this information and increase concurrency in your application.

  2. You can use Apache Commons you to do that too!

e.g:

public void getAll() throws Exception {
    FileAlterationObserver observer = new FileAlterationObserver(pathToSee);
    observer.addListener(new FileAlterationListenerAdaptor() {

        @SneakyThrows
        @Override
        public void onFileCreate(File file) {
            
            
        }

        @Override
        public void onFileDelete(File file) {
            
        }
    });
}

huangapple
  • 本文由 发表于 2020年9月4日 05:34:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/63731952.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定