一、代码实现
1、简单案例
这个代码很简单,只需要四步:
public static void main(String[] args) throws Exception { //第一步:取得WatchService WatchService watchService = FileSystems.getDefault().newWatchService(); //第二步:确定要监控的路径 Path path = Paths.get("G:\\"); //第三步:为本路径绑定WatchService,并确定监控的事件 path.register( watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY); WatchKey key; //第四步:当有事件时,开始触发 while ((key = watchService.take()) != null) { for (WatchEvent<?> event : key.pollEvents()) { System.out.println("事件" + event.kind() + "发生了,文件是:" + event.context()); } key.reset(); } }
这里我们监控G盘,然后我们在G盘新建文件,然后删除修改,就会在后台打印相关信息。
现在就可以监控了,很简单。
2、代码分析
第一步和第二步,新建一个取得WatchService和取得要监控的路径,这个很容易理解。
第三步绑定,这里只需要注意两件重要的事情:首先,path
将watchService
作为第一个参数,然后是StandardWatchEventKinds的变量参数。一共有四种。
- StandardWatchEventKinds.ENTRY_CREATE—当有新文件时触发。可能是创建了一个新文件。
- StandardWatchEventKinds.ENTRY_MODIFY—当文件被修改时触发。所有的文件编辑都会触发这个事件。在一些平台上,甚至改变文件属性也会触发它。
- StandardWatchEventKinds.ENTRY_DELETE—当文件被删除、移动或重命名时触发。
- StandardWatchEventKinds.OVERFLOW—触发表示丢失或丢弃的事件。
第四步不断监控,当watchService里面不为空时,开始获取相应的事件,并poll弹出。最后还有一个reset 表示回退到相应的句柄,继续处理下一次事件。
3、源码分析
由于watchService是一个接口,所以分析起来也比较简单。里面一共包含了三个方法
//方法1:关闭watchService @Override void close() throws IOException; //方法2:弹出事件 WatchKey poll(); //方法3:带有参数的弹出 WatchKey poll(long timeout, TimeUnit unit) throws InterruptedException; //方法4:获取事件。 WatchKey take() throws InterruptedException;
由于方法比较简单,所以我们可以直接看方法上的注释就可以了。
结论
WatchService接口是在java7
的版本中引入的。主要是处理NIO的文件相关问题。但是WatchService其实是有很多缺点的。
- WatchService是采用扫描式的,效率低。
- WatchService代码写起来费劲。虽然上面看起来很简洁了,但是实际开发时麻烦。
- WatchService不能监听到多级目录,事先父文件夹需要存在。
鉴于以上原因,在简单的实现时,可以使用,但是还有一个更强大的工具commons-io
,使用更简单也更加的高效。下篇文章给出。