rx-filewatcher.java,基于 NIO WatchService 的 Reactive 封装

栏目: 编程语言 · 发布时间: 7年前

内容简介:嫌我啰嗦的话,直接看代码:在写个小东西需要监控文件改变状态的时候,用到了 NIO 东西很方便也好用。但是,在使用首先,使用原生的接口必须开启个线程,然后使用个持续循环去读取 WatchEvent (这也是大部分教程描述这样子做的):

嫌我啰嗦的话,直接看代码: https://github.com/mingcheng/rx-filewatcher.java

在写个小东西需要监控文件改变状态的时候,用到了 NIO 东西很方便也好用。但是,在使用 WatchService 的时候碰到了些问题。

首先,使用原生的接口必须开启个线程,然后使用个持续循环去读取 WatchEvent (这也是大部分教程描述这样子做的):

WatchKey key;
while ((key = watchService.take()) != null) {
    for (WatchEvent<?> event : key.pollEvents()) {
        //process
    }
    key.reset();
}

这样子做有几个不好的地方:一是开了个匿名线程,如果后期代码也有类似的情况,线程就不好处理,而且很容易无法监控到这个线程的状态;第二就是破坏了代码原有的业务逻辑,读到这里如果阅读代码的小伙伴不熟悉 WatchService 就很难理解。

其次, WatchService 的注册是一次性的,也就是说无法监控到子目录以下的情况,必须随时监控是否创建了子目录然后再对应 register 子目录 watch(这样子一个简单的功能就会搞得非常的复杂)。

我考虑到使用 Rx 重写这块的代码, 然后翻阅 Github 的时候发现已经有人造了这个轮子 。代码量不大,但核心功能是我想要的,只是最新更新已经在三年前了。

集成了 Helmbold 这个哥们的库以后,又发现了几个问题:

1. 这个库是写在三年前的,还在用 Rx1 的库,和我目前的 Rx2 有部分的不兼容;
2. dispose 部分有问题,dispose 以后线程没有终止还在运行; 
3. 获取到 WatchEvent 的 Context 只有文件名没有路径。

因为代码量本身就不是很多,同时考虑到这块还是需要以后自己维护, 因此 fork 了他的代码自己做了些改造

对比以上的原生代码,使用 Rx 封装的代码就会干净和直观很多:

PathObservables
  .subscribeOn(Schedulers.io())
  .watchRecursive(Paths.get("some/directory/"))
  .subscribe(event -> System.out.println(event));

然后,基本上已经满足了我的需求。

顺便说下,WatchService 里面还有个坑,就是使用网络磁盘映射的时候,可能会造成 WatchEvent 会有丢失, 在这里有详细的讨论,这是目前 NIO 已知的 Bug 。如果你对文件状态监控要求实时性比较高,建议不要使用 WatchService 使用其他的方案。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

High Performance JavaScript

High Performance JavaScript

Nicholas C. Zakas / O'Reilly Media / 2010-4-2 / USD 34.99

If you're like most developers, you rely heavily on JavaScript to build interactive and quick-responding web applications. The problem is that all of those lines of JavaScript code can slow down your ......一起来看看 《High Performance JavaScript》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具