文件目录发生了增删改操作?Java如何实时监控?

开发 后端
有时候你可能有个疑问,IDE总是可以检测到外部文件是否发生了变化,比如你在某个类里面加了一些代码,这时候的IDE就会弹出一个框说你做了更改。

前言

有时候你可能有个疑问,IDE总是可以检测到外部文件是否发生了变化,比如你在某个类里面加了一些代码,这时候的IDE就会弹出一个框说你做了更改。再或者是某个文件夹下的文件发生了改变,比如新建了一个或者是删除了一个等等。这时候我们的IDE依然可以检测到。这个功能到底是如何实现的呢?这篇文章主要是研究NIO的其中一个类,叫做WatchService。

也有一些其他的方式可以轻松地实现监控文件夹的功能,比如说java轮询的方式,或者是common-io的方式,我会慢慢比较。

OK,我们直接来看一下简单例子如何实现,再去分析如何实现的?

一、代码实现1、简单案例

这个代码很简单,只需要四步:

  1. public static void main(String[] args) throws Exception { 
  2.    //第一步:取得WatchService 
  3.    WatchService watchService = FileSystems.getDefault().newWatchService(); 
  4.    //第二步:确定要监控的路径 
  5.    Path path = Paths.get("G:\\"); 
  6.    //第三步:为本路径绑定WatchService,并确定监控的事件 
  7.    path.register( 
  8.        watchService, 
  9.        StandardWatchEventKinds.ENTRY_CREATE, 
  10.        StandardWatchEventKinds.ENTRY_DELETE, 
  11.        StandardWatchEventKinds.ENTRY_MODIFY); 
  12.    WatchKey key
  13.    //第四步:当有事件时,开始触发 
  14.    while ((key = watchService.take()) != null) { 
  15.        for (WatchEvent<?> event : key.pollEvents()) { 
  16.           System.out.println("事件" + event.kind() + "发生了,文件是:" + event.context()); 
  17.        } 
  18.        key.reset(); 
  19.    } 

这里我们监控G盘,然后我们在G盘新建文件,然后删除修改,就会在后台打印相关信息。

 

现在就可以监控了,很简单。

2、代码分析

第一步和第二步,新建一个取得WatchService和取得要监控的路径,这个很容易理解。

第三步绑定,这里只需要注意两件重要的事情:首先,path将watchService作为第一个参数,然后是StandardWatchEventKinds的变量参数。一共有四种。

  • StandardWatchEventKinds.ENTRY_CREATE—当有新文件时触发。可能是创建了一个新文件。
  • StandardWatchEventKinds.ENTRY_MODIFY—当文件被修改时触发。所有的文件编辑都会触发这个事件。在一些平台上,甚至改变文件属性也会触发它。
  • StandardWatchEventKinds.ENTRY_DELETE—当文件被删除、移动或重命名时触发。
  • StandardWatchEventKinds.OVERFLOW—触发表示丢失或丢弃的事件。

第四步不断监控,当watchService里面不为空时,开始获取相应的事件,并poll弹出。最后还有一个reset 表示回退到相应的句柄,继续处理下一次事件。

3、源码分析

由于watchService是一个接口,所以分析起来也比较简单。里面一共包含了三个方法

  1. //方法1:关闭watchService 
  2. @Override 
  3. void close() throws IOException; 
  4. //方法2:弹出事件 
  5. WatchKey poll(); 
  6. //方法3:带有参数的弹出 
  7. WatchKey poll(long timeout, TimeUnit unit) 
  8.         throws InterruptedException; 
  9. //方法4:获取事件。 
  10. WatchKey take() throws InterruptedException; 

由于方法比较简单,所以我们可以直接看方法上的注释就可以了。

结论

WatchService接口是在java7的版本中引入的。主要是处理NIO的文件相关问题。但是WatchService其实是有很多缺点的。

WatchService是采用扫描式的,效率低。

WatchService代码写起来费劲。虽然上面看起来很简洁了,但是实际开发时麻烦。

WatchService不能监听到多级目录,事先父文件夹需要存在。

鉴于以上原因,在简单的实现时,可以使用,但是还有一个更强大的工具commons-io,使用更简单也更加的高效。下篇文章给出。

 

责任编辑:武晓燕 来源: 愚公要移山
相关推荐

2023-03-31 08:12:30

操作系统nanosleep信号

2019-09-16 17:16:29

Hadoop数据湖数据结构

2022-12-13 10:59:47

devtoolMemory

2021-08-30 13:08:54

Linux实时监控日志文件

2019-11-07 15:39:36

数据库MySQL文章

2021-08-09 13:34:14

Python开发数据

2020-10-29 08:39:45

JSONJava对象

2023-02-27 07:37:56

Curl操作SQL

2019-11-12 14:41:41

Redis程序员Linux

2016-10-13 19:16:28

Python编程语言mysql

2023-06-08 08:13:43

2020-08-17 12:47:07

Mozilla裁员浏览器

2019-08-26 09:35:25

命令ping抓包

2010-02-07 09:00:29

AndroidLinux Kerne

2017-12-28 15:40:16

开源LinuxGitHub

2021-01-18 08:23:23

内存时底层CPU

2021-04-11 10:40:16

Git软件开发

2023-11-16 08:00:00

Datadog部署实时监控

2020-09-01 11:40:01

HTTPJavaTCP

2015-07-03 09:27:43

网络闰秒
点赞
收藏

51CTO技术栈公众号