在Java 7的所有新功能中,更有趣的是WatchService,它增加了监视目录更改的功能。 WatchService直接映射到本机文件事件通知机制(如果有)。

如果本机事件通知机制不可用,则默认实现将使用轮询。 结果,响应性,事件的顺序和可用细节是特定于实现的。 (注意:有一篇有关使用Guava EventBus处理WatchService事件的文章 )

观看目录

Path接口实现了将WatchService对象和WatchEvent.Kind类型的varargs作为参数的register方法。 有4个事件需要注意:

  1. ENTRY_CREATE
  2. ENTRY_DELETE
  3. ENTRY_MODIFY
  4. 溢出

前三种是不言自明的,而OVERFLOW则表示事件可能丢失或丢弃。 通过调用FileSystem.newWatchService()创建WatchService。 观看目录是通过在WatchService中注册Path对象来完成的:

import static java.nio.file.StandardWatchEventKinds.*;
Path path = Paths.get("/home");
WatchService watchService = FileSystems.getDefault().newWatchService();
WatchKey watchKey = path.register(watchService,ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY);

从示例中可以看到,register方法返回一个WatchKey对象。 WatchKey是表示在WatchService中注册路径的令牌。

WatchKey

作为注册过程的结果,WatchKey处于“就绪”状态,并被视为有效。 WatchKey保持有效,直到发生以下情况之一:

  1. WatchKey.cancel()被调用。
  2. 正在监视的目录不再可用。
  3. WatchService对象已关闭。

检查变更

当检测到更改时,WatchKey状态将设置为“已信号发送”,并将其放入队列中进行处理。 使WatchKeys脱离队列涉及调用WatchService.poll()或WatchService.take()。 这是一个基本示例:

private boolean notDone = true;
while(notDone){try{WatchKey watchKey = watchService.poll(60,TimeUnit.SECONDS);List<WatchEvent.Kind<?>> events = watchKey.pollEvents();for(WatchEvent event : events){...process the events}if(!watchKey.reset()){...handle situation no longer valid}}catch(InterruptedException e){Thread.currentThread().interrupt();}

在第5行上,我们调用pollEvents方法来检索此WatchKey对象的所有事件。 在第9行,您会注意到对reset方法的调用。 reset方法将WatchKey状态重新设置为“就绪”,并返回一个布尔值,指示WatchKey是否仍然有效。 如果有任何未决事件,则WatchKey将立即重新排队,否则它将保持就绪状态,直到检测到新事件。 在已取消或处于就绪状态的WatchKey上调用reset无效。 如果WatchKey在排队时被取消,它将在队列中扩大直到被取回。 如果目录已删除或不再可用,取消也会自动发生。

处理事件

现在我们已经检测到一个事件,我们如何确定:

  1. 事件发生在哪个目录? (假设注册了多个目录)
  2. 实际事件是什么? (假设收听多个事件)
  3. 事件的目标是什么,即创建,删除或更新了哪个Path对象?

跳到上一个示例的第6行,我们将从WatchKey和WatchEvent中解析所需的信息:

//WatchKey watchable returns the calling Path object of Path.registerPath watchedPath = (Path) watchKey.watchable();//returns the event typeStandardWatchEventKinds eventKind = event.kind();//returns the context of the eventPath target = (Path)event.context();

在第6行,我们看到了WatchEvent.context方法被调用。 如果事件是创建,删除或更新,并且该事件相对于监视目录,则context方法将返回Path对象。 重要的是要知道,当收到事件时,不能保证执行该操作的程序已经完成,因此可能需要一定程度的协调。

结论

WatchService是Java 7中新的java.nio.file包的一个非常有趣的功能。也就是说,WatchService需要牢记两件事:

  1. WatchService不会为监视目录的子目录拾取事件。
  2. 我们仍然需要轮询WatchService的事件,而不是接收异步通知。

为了解决上述问题,有一篇后续文章,使用Guava EventBus处理WatchService事件 。 感谢您的宝贵时间,在下一篇文章中见。


资源资源

  1. java.nio.file软件包,其中包含此处讨论的WatchService,WatchKey和WatchEvent对象。
  2. 演示WatchService的单元测试

参考: Java 7的新增功能: JCG合作伙伴提供的 WatchService   比尔·贝杰克(Bill Bejeck)在“ 编码随机思想”博客上。

翻译自: https://www.javacodegeeks.com/2012/02/java-7-watchservice.html

Java 7:WatchService相关推荐

  1. JAVA 文件监控 WatchService

    概述 java1.7中 提供了WatchService来监控系统中文件的变化.该监控是基于操作系统的文件系统监控器,可以监控系统是所有文件的变化,这种监控是无需遍历.无需比较的,是一种基于信号收发的监 ...

  2. java 终极超类,Java问答:终极父类(3),java问答

    Java问答:终极父类(3),java问答Java问答:终极父类(上) Java问答:终极父类(下) Java问答:终极父类(2)-上篇 Java问答:终极父类(2)-下篇 在之前关于 Object ...

  3. public接口可以被任何一个类实现_一文带你深入Java核心技术:对象克隆+接口与回调,还有这种操作...

    对象克隆 当拷贝一个变量时,原始变量与拷贝变量引用同一个对象,如图6-1所示.这就是说,改变一个变量所引用的对象将会对另一个变量产生影响. Employee original = new Employ ...

  4. 清华学霸花了三年时间对java理解: Java分布式架构

    什么是分布式架构 分布式系统(distributed system)是建立在网络之上的软件系统. 内聚性是指每一个数据库分布节点高度自治,有本地的数据库管理系统. 透明性是指每一个数据库分布节点对用户 ...

  5. Java线程:线程的调度-合并

    Java线程:线程的调度-合并 线程的合并的含义就是将几个并行线程的线程合并为一个单线程执行,应用场景是当一个线程必须等待另一个线程执行完毕才能执行时可以使用join方法. join为非静态方法,定义 ...

  6. Java项目: 基于SSM实现教务管理系统

    系统编号:BS-GX-020 后台技术:Spring+Springmvvc+mybatis+shiro 前端技术:Bootstrap+jquery+ajax 页面开发:JSP 开发工具:IDEA  或 ...

  7. Java线程:新特征-条件变量(转)

    条件变量是Java5线程中很重要的一个概念,顾名思义,条件变量就是表示条件的一种变量.但是必须说明,这里的条件是没有实际含义的,仅仅是个标记而已,并且条件的含义往往通过代码来赋予其含义. 这里的条件和 ...

  8. Java Hashmap:如何从价值中获取关键?

    如果我的值是"foo" ,并且ftw.containsValue("foo")返回true的HashMap<String> ftw ,如何获得相应的 ...

  9. Java笔记:成员变量,局部变量,类变量,实例变量以及注意事项

    局部变量:方法中定义的变量. 成员变量(类似C中的全局变量):成员变量定义在方法体和语句块之外.成员变量就概括描述了类中的变量,不区分static.是以下变量的统称. 类变量(静态变量):独立于方法之 ...

最新文章

  1. vue实现文件上传功能
  2. xml命名空间只是标记区分不同的空间的作用,一般与上网无关,虽然通常都写的是URL网址
  3. canva旋转图片 js_js和canvas实现旋转图片
  4. (面试题)删除在另一个字符串中出现的字符
  5. 华为Mate 30系列5G版屠榜双十一:当之无愧的5G爆品
  6. C语言原码、反码、补码
  7. 通过驱动向Excle中写入数据
  8. 【手势识别】基于matlab PCA+LDA手语检测识别【含Matlab源码 1551期】
  9. 小甲鱼python笔记_小甲鱼Python笔记(类)
  10. 为什么以太网有最短帧长度的要求_线束工程师:车载以太网介绍
  11. python平均值和加权平均值
  12. 如何更换您的Gmail地址
  13. STM32HAL库微秒延时函数的实现---DWT和SysTick
  14. 网络基础(二)之HTTP与HTTPS
  15. HoughCircles()函数 画圆心和圆的轮廓
  16. 蘑菇街的开源IM:TeamTalk
  17. 1.5 mysql练习题37道,做完这些mysql练习题,立马让你进阶。(附答案)
  18. 用计算机打青春不打烊,彩色的青春不打烊
  19. Linux系统无名管道通信实验,Linux进程间通信(二)---管道通信之无名管道及其基础实验...
  20. knn可视化、稠密dsift原理、手势识别

热门文章

  1. ibatis(1)ibatis的理念
  2. java中的native关键字有什么作用?(java本地方法)
  3. 网页益智游戏怎么制作_休息一下,或者:如何使用Java 12制作出色的益智游戏...
  4. netflix 模式创新_创新设计模式:单例模式
  5. 琥珀ai_琥珀项目:Java的未来暴露
  6. jhipster_jHipster入门,第1部分
  7. 服务器编写_编写下载服务器。 第六部分:描述您发送的内容(内容类型等)...
  8. 使用适用于Java 2的AWS开发工具包的AWS DynamoDB版本字段
  9. 前6个最常用的Redis库
  10. Spring @RequestParam批注