文件目录的增删改操作?java如何实时监控?

前言

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

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

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

一、代码实现

1、简单案例

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

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

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

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

2、代码分析

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

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

  • StandardWatchEventKinds.ENTRY_CREATE—当有新文件时触发。可能是创建了一个新文件。
  • StandardWatchEventKinds.ENTRY_MODIFY—当文件被修改时触发。所有的文件编辑都会触发这个事件。在一些平台上,甚至改变文件属性也会触发它。
  • StandardWatchEventKinds.ENTRY_DELETE—当文件被删除、移动或重命名时触发。
  • StandardWatchEventKinds.OVERFLOW—触发表示丢失或丢弃的事件。
  • 第四步不断监控,当watchService里面不为空时,开始获取相应的事件,并poll弹出。最后还有一个reset 表示回退到相应的句柄,继续处理下一次事件。

    3、源码分析

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

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

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

    结论

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

  • WatchService是采用扫描式的,效率低。
  • WatchService代码写起来费劲。虽然上面看起来很简洁了,但是实际开发时麻烦。
  • WatchService不能监听到多级目录,事先父文件夹需要存在。
  • 鉴于以上原因,在简单的实现时,可以使用,但是还有一个更强大的工具commons-io,使用更简单也更加的高效。下篇文章给出。

    java小白到架构师技术图谱(整理全网,持续更新)

    2T后端教程,5000本电子书,1T面试资料,都在这里

    相关文章

    Java之文件删除 java 删除文件夹下的文件

    package com.biubiu.utils; import java.io.File; public class Utils { /** * 删除文件 *...

    delete()方法删除文件及目录 delete all files

    在Java中,可以使用delete()方法来删除文件或目录。该方法是File类中的一个方法,接受一个File对象作为参数,并尝试删除该文件或目录。如果该文件或目录成功删除,该方法返回true,否则返回...

    教你如何彻底干净的卸载Java 如何完全卸载java

    一、删除环境变量右键此电脑,属性高级系统设置点击环境变量找到Java相关的系统变量,将其删除在系统变量中找到path,将其中与Java相关的删除二、卸载Java打开控制面板“程序和功能”,卸载与Jav...

    已满的C盘如何清理无用的文件 c盘已满怎么清理

    一、假设电脑(C盘总共80G)为例:1;Program Files 占用了 1.53G2;Program Files(X86) 占用了 4.68G3;ProgramData 占用了 2.8G4; Wi...

    快速释放C盘空间,从清理Windows文件夹开始

    新安装的系统还没用多久,突然提示系统备份空间不足?光是 C 盘中 Windows 文件夹就已经占用了54.3G空间,再仔细看了一下,其中 WinSxS 文件夹占用了22.1G空间。C盘 Windows...

    五年开发,你还记得Java基础代码中的文件I/O操作么?

    文件I/O操作作为Java开发中的一个重要组成部分,主要负责Java代码中对于文件的读写操作,可能对于一些长时间不使用Java文件API的开发者来说早都忘记了相关的操作,下面我们就来详细介绍一下Jav...