Java 1.6版本之前是不存在目录监控的API的。若是要实现这种功能必需要本身遍历目录,记录各个文件的状况,而后定时所有遍历一次,从 JDK7 以后出现了 WatchService
类,实现了对目录下文件的监控。java
整个监控目录文件操做的流程大体以下:操作系统
WatchService
类的实现其实是对操做系统的文件监视器的封装,相比以前的手动实现,优雅了很多。由于不须要遍历文件总体而言效率也高不少。如下为获取 WatchService
实例的代码,经过 FileSystem.getDefault() 可看出并不是是本身实现的。从 newWatchService()
方法名看, WatchService
能够获取多个。.net
WatchService watchService = FileSystems.getDefault().newWatchService();
实际上调用此方法后,程序会新开一个线程,监视文件变化发出的信号,此时线程还没有就绪。线程
有了监视器,接下来咱们须要注册监视器了。code
Path path = Paths.get("src"); WatchKey watchKey = path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
注册监视器须要用到 Path
实例,该实例对应的必须是一个目录,不容许是一个文件。
方法比较简单,就是说为目录注册一个监视器,监视目录下文件的变化。
关于 StandardWatchEventKinds.ENTRY_MODIFY
,表示监视文件的修改事件,它是 WatchEvent.Kind<?>
的实现类。
看起来它像是枚举,实际上它并非。JDK 中帮咱们定义了三种事件,新增、修改和删除。orm
获取目录的变化须要使用 WatchService
的 take()
方法或 poll()
方法。对象
WatchKey key = watchService.take(); WatchKey pollKey = watchService.poll();
take()
是一个阻塞方法,会等待监视器发出的信号才返回。poll()
是一个非阻塞方法,会当即返回当时监视器中是否有信号。
返回的 WatchKey
对象,其实是一个单例,和以前 path.register()
方法返回的实例是同一个。它只能保存某一时间点的文件变化信息。blog
List<WatchEvent<?>> events = key.pollEvents(); for (WatchEvent<?> pollEvent : events) { Object o = pollEvent.context(); WatchEvent.Kind kind = pollEvent.kind(); } key.reset();
pollEvents()
用于获取文件变化事件,只能获取一次,不能重复获取,相似队列的形式。context()
返回触发该事件的那个文件或目录的路径(相对路径)kind()
返回事件类型(ENTRY_CREATE、ENTRY_DELETE、ENTRY_MODIFY之一)reset()
每次调用 WatchService 的 take() 或 poll() 方法时须要经过本方法重置。队列
public void watchServiceExample() throws IOException, InterruptedException { WatchService watchService = FileSystems.getDefault().newWatchService(); Path path = Paths.get("D:/code"); WatchKey watchKey = path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY); while (true) { // 尝试获取下一个变化信息的监控池,若是没有变化则一直等待 WatchKey key = watchService.take(); for (WatchEvent<?> pollEvent : key.pollEvents()) { System.out.println(String.format("%s is %s.", pollEvent.context().toString(), pollEvent.kind().name().substring(6))); } if (!key.reset()) { break; } } }
WatchService 的优势就不用多说了,这里就说一个缺点: 只能监视当前目录下的文件和目录,不能监视子目录 。事件
参考
[疯狂Java]NIO.2:WatchService、WatchKey(监控文件变化)
本文若有问题,欢迎在评论区中指正。