文档章节

java如何写一个高效率的及时获取更新文件改动的方式

xpbob
 xpbob
发布于 2017/03/31 22:25
字数 845
阅读 321
收藏 4

场景

      在很多要多次读取配置文件的场所中,想要让修改文件后,尽快的读取到新的配置。

常用的解决方式

        常见的解决方式一般是使用轮训的方式。就是开启一个线程定时的去轮训配置文件的最后修改时间,如果修改时间和上次不同,就重新读取配置文件的内容。

        以上的方法比较浪费资源,因为你的cpu要不停的去轮转判断,而且固定的时间间隔太长的话会造成信息修改不及时的问题。

新特性描述

      在java7中加入了一个新功能,目录监控,解决了上面描述的问题。这个版本提供了一个WatchService。这个类的作用就是可以去注册文件夹和相应的事件。常见的事件就是创建,删除和改变。当发生相应事件的时候,就可以去获取到发生事件的文件或者文件夹,从而达到了及时获取到变化。这样就带来一个好处,想关注配置文件的变化的时候,就在文件所在的文件夹上注册相应的事件,一般就是注册改变事件。

 编写方式

         所有的文件注入都是相似的。所有这个编程就是一个规范化的东西。

         首先获取到WatchService对象

WatchService watcher = FileSystems.getDefault().newWatchService();

        我们监控的是文件夹,所有现在文件系统的WatchService

        然后我们需要获取到想注册事件的文件夹dir,是一个Path类型,然后在service上注册事件,这里我们注册一个改变事件就行。

dir.register(watcher, ENTRY_MODIFY);

        然后就是通过事件的监听来获取改变的情况,WatchService可以通过take或者poll方法来轮训,take是阻塞的,poll是非阻塞的,这个根据具体场景来选择,下面选择take,这样可以省去一部分cpu的消耗。

WatchKey key = watcher.take();

        通过这个方法可以获取一个watchkey,他的pollEvents方法就会返回所有的有相应的事件。我们选择使用for循环去遍历。

for (WatchEvent<?> event : key.pollEvents())

        也可以根据这个key来获取到监控的目录

Path dir = (Path) key.watchable();

        根据event强制转化为一个Path,可以根据context方法获取一个路径。

        然后根据path的方法,就可以获取到改变文件的全路径了。

Path child = dir.resolve(name);

编写方式优化

        由于上面的编码其实是比较有规范的,我就把这些功能直接抽象包装一下。并且分享出来

        https://git.oschina.net/xpbob/commonIO.git

        如何还需要上面的模式,就精简到下面的几行代码

        final DirWatcher dw = new DirWatcher(true);
		dw.registerAllEvents(Paths.get("c:/hello")).addHandler(new WatcherResultHandler() {

			public void handleResult(Path path, Kind<?> event) {
				System.out.println(path.toString() + ": " + event.toString());
			}
		}).processEvents();

        精简后,我们只要输入监控的目录,然后实现一个WatcherResultHandler借口,完成一个回调。

        handleResult(Path path, Kind<?> event) 这里的第一个参数就是文件,第二个参数就是相应的事件,通过上面的操作,我们就能只关心我们的业务流程,而不用写很繁琐的操作了。

© 著作权归作者所有

xpbob

xpbob

粉丝 98
博文 96
码字总数 77864
作品 0
高级程序员
私信 提问
JDK 9 中一些需要提防的坑

JDK 9正处于开发的最后阶段, 向着9月21号的发布目标冲刺。Java 平台模块系统的公开评审投票基本上被一致通过,所以目前一切都可以回归正常了。 你可在此处下载 OpenJDK 9 (尝鲜版)。 最近我...

oschina
2017/09/11
3.2K
2
Scala笔记整理(二):Scala数据结构—数组、map与tuple

[TOC] 数组 定长数组 如果你需要一个长度不变的数组,可以用Scala中的Array。例如: 在JVM中,Scala的Array以Java数组方式实现。示例中的数组在JVM中的类型为java.lang.String[]。Int、Doubl...

xpleaf
2018/04/18
0
0
Java Web Start实践:动态生成JNLP

Java很早就推出了Java Web Start(简称JWS)技术。这一技术的初衷很好:希望将桌面程序和Web页面之间搭起一个无缝的桥梁。虽然Applet技术已经存在了十多年,但是它 日趋老迈衰落,所以JWS也就...

dodojava
2012/05/23
0
0
Java 8新的时间日期库的20个使用示例

除了lambda表达式,stream以及几个小的改进之外,Java 8还引入了一套全新的时间日期API,在本篇教程中我们将通过几个简单的任务示例来学习如何使用Java 8的这套API。Java对日期,日历及时间的...

清尘V
2015/03/17
0
0
最近5年183个Java面试问题列表及答案[最全]

Java面试随着时间的流逝而改变。在过去,当你知道String和StringBuilder的区别(String类和StringBuilder类的主要区别在于String是不可变的对象。因此灭此对String对象进行改变的时候其实都等...

圣洁之子
03/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

面试爱奇艺,竟然挂在第5轮……

今天给大家分享我曾经在爱奇艺的面试,过程还是比较有意思的,可以给大家一些参考 <br> 聊骚阶段 嗲妹妹:你好,我是爱奇艺的HR,我们正在招聘运维开发岗位,请问您最近有在看工作机会吗? ...

上海小胖
20分钟前
0
0
Jenkins系列_插件安装及报错处理

进入Jenkins之后我们可以进行插件的安装,插件管理位于以下模块: 发现上面报了一堆错误,是因为插件的依赖没有安装好,那么这一节,就先把这些错误解决掉吧。解决完成后,也就基本会使用插件...

shzwork
今天
2
0
mysql mysql的所有查询语句和聚合函数(整理一下,忘记了可以随时看看)

查询所有字段 select * from 表名; 查询自定字段 select 字段名 from 表名; 查询指定数据 select * from 表名 where 条件; 带关键字IN的查询 select * from 表名 where 条件 [not] in(元素...

edison_kwok
昨天
9
0
解决多线程并行加载缓存问题(利用guava实现)

依赖 com.google.guava:guava:20.0 import com.google.common.cache.Cache;import com.google.common.cache.CacheBuilder;import java.util.concurrent.ExecutionException;import j......

暗中观察
昨天
4
0
利用VisualVM 内存查看

准备工作,建几个测试类。等下就是要查看这几个类里面的属性 package visualvm;public class MultiObject { private String str; private int i; MultiObject(String str...

冷基
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部