Java NIO之文件监控机制
来源:互联网 发布:java游戏引擎 编辑:程序博客网 时间:2024/06/06 02:25
由于业务需要在主备切换时读取程序返回值文件,这样一来就涉及到了文件监控读取的问题,比较low的做法是程序备进程变主进程后每隔一段时间去轮询相关的文件,并读取里面的返回值。后来突然想到了socket相关有个NIO机制,于是觉得socket和文件对操作系统其实都是外设,应该有相关的NIO机制。后来发现java单独提供了一个很好用的NIO相关机制。
例子比较简单,直接分析:
WatchService watcher = null;
Pathpath1 = Paths.get("D:\\data2");
Pathpath2 = Paths.get("D:\\data");
try{
watcher= FileSystems.getDefault().newWatchService();
path1.register(watcher,ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY);
path2.register(watcher,ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY);
}catch (IOException e1) {
//TODO Auto-generated catch block
e1.printStackTrace();
}
while(true){
try{
WatchKeykey = watcher.take();
for(WatchEventevent : key.pollEvents()){
System.out.println(key.toString());
WatchEvent.Kindkind = event.kind();
WatchEvente = (WatchEvent)event;
Path fileName = (Path)e.context();
System.out.printf("Event%s has happened,which fileName is %s%n"
,kind.name(),fileName);
key.reset();
}
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
1.首先创建两个Path对象,其实就是文件节点对象
2.由于windows和linux系统的watcher实现类是不同的,所以需要watcher= FileSystems.getDefault().newWatchService();动态获取当前文件系统的watcher实现类对象。
3. 对1创建的两个Path对象进行watcher注册,监控两个Path的一举一动。(注意NIO只能监控到Path对象本身和它的子文件或者子目录一层)
path1.register(watcher,ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY);
path2.register(watcher,ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY);
--其中ENTRY_CREATE,ENTRY_DELETE,ENTRY_MODIFY是要监控的事件,不声明的事件将不会触发通知。
4. 接下来在死循环中调用WatchKeykey = watcher.take();进行阻塞等待事件,当watcher发现有需要监控的事件发生时会唤醒阻塞线程,进行下一步操作。
5. 在子循环中,获得相关的发生的事件,for(WatchEventevent : key.pollEvents()),并迭代打印相关事件的具体信息。
6. 最后要重新设置key.reset();,使之在下次循环中再次阻塞等待
进一步分析:
根据源码进一步深入分析,会发现,整个NIO监控机制实际是使用了生产者消费者模式的方式来实现的。
sun.nio.fs.WindowsWatchService.take()
实际是使用了父类的方法:
AbstractWatchService.take()
private finalLinkedBlockingDeque<WatchKey> pendingKeys =
new LinkedBlockingDeque<WatchKey>();
public final WatchKey take()
throws InterruptedException
{
checkOpen();
WatchKey key = pendingKeys.take();
checkKey(key);
return key;
}
--可见是用到了LinkedBlockingDeque这个阻塞队列容器的take()方法
public E take() throws InterruptedException{
return takeFirst();
}
---------à
private final Condition notEmpty =lock.newCondition();
public E takeFirst() throwsInterruptedException {
finalReentrantLock lock = this.lock;
lock.lock();
try {
E x;
while ( (x = unlinkFirst()) == null)
notEmpty.await();
return x;
} finally {
lock.unlock();
}
}
---看到没,典型的生产者消费者模式,当队列容器为空时,则阻塞等待,当往队列中填写元素时就唤醒阻塞线程:
private boolean linkFirst(Node<E> node) {
// assert lock.isHeldByCurrentThread();
if (count >= capacity)
return false;
Node<E> f = first;
node.next = f;
first = node;
if (last == null)
last = node;
else
f.prev = node;
++count;
notEmpty.signal();
return true;
}
比较好的参考资料:
http://blog.csdn.net/lirx_tech/article/details/51425364
- Java NIO之文件监控机制
- java 7 /java.nio.file 文件监控!!!
- 利用Java NIO 实现文件监控功能。
- [疯狂Java]NIO.2:WatchService、WatchKey(监控文件变化)
- Java nio 之 内存映射文件
- Java NIO 之对文件锁支持
- java NIO工作机制
- Java NIO机制
- Java NIO工作机制
- Java 文件监控,实时监控文件加载之Commons-io
- Java 文件监控,实时监控文件加载之Commons-io
- Java NIO 之 NIO 简介
- Java实现文件监控之二
- Java NIO-锁机制Lock
- java nio 文件锁小例
- java nio 文件锁小例
- Java NIO 写文件
- JAVA NIO 文件保存
- 如何做好一条0~2岁的产品狗
- 产品经理一定要理解数据
- 深度解读「楼下100」撬动下午茶市场 |手摸手产品研究院
- eclipse官网下载收费 怎么办?
- HDU5556 Land of Farms(最大独立集)
- Java NIO之文件监控机制
- 3DSlicer33:Adding MRML
- ubuntu16.04+cuda8.0+cudnn6+tensorflow安装
- 从豆瓣电影评分算法说起
- 资本寒冬,这十大创业公司值得尊重(上)
- 右值 移动
- 协同过滤-皮尔逊相关系数算法
- Angular4 环境搭建与项目创建与发布
- 利用python进行数据分析译者给出的注意事项