nio监控文件变化

Updated on in 程序人生 with 0 views and 0 comments

简介

nio主要是通过WatchService、Watchkey和Path来实现文件的监控;

代码实现

public class FileMonitor {

    private WatchService watcher;

    public FileMonitor(String directory) throws IOException {
        watcher = FileSystems.getDefault().newWatchService();
        Path path = Paths.get(directory);
        path.register(watcher, ENTRY_CREATE, ENTRY_MODIFY,ENTRY_DELETE);
    }

    @SuppressWarnings("InfiniteLoopStatement")
    public void watchFile() throws InterruptedException{
        while (true) {
            WatchKey key = watcher.take();
            for (WatchEvent<?> event : key.pollEvents()) {
                WatchEvent.Kind<?> kind = event.kind();
                if (kind.equals(ENTRY_CREATE)) {
                    System.out.println("新文件");
                } else if (kind.equals(ENTRY_MODIFY)) {
                    System.out.println("修改文件");
                } else if (kind.equals(ENTRY_DELETE)) {
                    System.out.println("删除文件");
                } else if (kind.equals(OVERFLOW)) {
                    System.out.println("文件操作遗失");
                } else {
                    System.out.println("不能识别的文件操作");
                }
                Path fileName = (Path) event.context();
                System.out.printf("发现 %s 操作,文件为 %s%n", kind.name(), fileName);
            }
            if(!key.reset()){
                break;
            }
        }
    }
}

基本原理

注册监控文件

Path接口中有一个register方法,第一个参数,指定了要注册到哪个监控服务,第二个参数表示要监控的文件操作类型

    WatchKey register(WatchService watcher,
                      WatchEvent.Kind<?>... events)
        throws IOException;

监控事件类型

监控类型存储在 StandardWatchEventKinds中,主要有以下类型:

  • OVERFLOW 表示一个特殊事件已丢失或遗弃
  • ENTRY_CREATE 表示文件创建
  • ENTRY_DELETE 表示文件删除
  • ENTRY_MODIFY 表示文件修改

监控服务

WatchService 的实现类 AbstractWatchService 中存储了这个监控服务监控的对象信息。

image.png

在这个类中,可以移除、新增、关闭监控服务。

而被监控的对象中又存储了自己被监控到哪个服务,使用了设计模式中的观察者模式。

image.png

通过这几个核心的类就可以实现监控啦。

注意

调用监控方法后,必须要调用 WatchKey的reset方法,因为watchkey有两个状态

image.png

监控到事件后,会被移除监控队列,状态会被为SIGNALLED,需要调用reset方法重置状态为READY,让监控对象重新进入监控队列;

监控到文件改变:

image.png

重置:

image.png

代码中调用reset方法后,会验证是否正常,所以要在自己的代码里做判断,如果返回不正常,则需要做处理,我的代码里只是做了一个简单的break,可以根据自己的需求自己处理


标题:nio监控文件变化
作者:wenyl
地址:http://www.wenyoulong.com/articles/2020/12/25/1608875157080.html