Java NIO.2 使用Path接口来监听文件、文件夹变化

 更新时间:2019年05月29日 08:53:59   作者:chenhongyong  
Java7对NIO进行了大的改进,新增了许多功能,接下来通过本文给大家介绍Java NIO.2 使用Path接口来监听文件、文件夹变化 ,需要的朋友可以参考下

Java7对NIO进行了大的改进,新增了许多功能:

•对文件系统的访问提供了全面的支持
•提供了基于异步Channel的IO

这些新增的IO功能简称为 NIO.2,依然在java.nio包下。

早期的Java只提供了File类来操作文件、文件夹本身,功能有限,性能也不高。

NIO.2为解决这种缺陷,提供了Path接口,并提供了Paths、Files2个工具类,这2个工具类包含的方法都是静态方法,Files类提供了大量的静态方法来操作文件、文件夹。

Path接口、Paths工具类使用示例:

//获取指定路径的Path对象
    Path path=Paths.get("D:/untitled/test/");  
    //也可以这样写:  Path path=Paths.get("D","untitled","test");  参数个数可变

    //返回文件/文件夹名,test
    System.out.println(path.getFileName());
    //返回父目录的路径,D:\untitled
    System.out.println(path.getParent());
    //判断该路径的最后一级是否是指定的文件/文件夹,true。和String的endsWith有点不同。当参数是最后一级的文件/文件夹名时,才返回true。
    System.out.println(path.endsWith("test"));  
    //以上方法的操作对象是Path对象中的路径,就是说路径不必是真实存在的

    //返回根路径(盘符),D:\
    System.out.println(path.getRoot());
    //返会绝对路径
    System.out.println(path.toAbsolutePath());  
    //以上获取的路径要是真实存在的

以前,如果要监控文件、目录的变化(新建、修改、删除),一般是启动一条后台线程,这条线程每隔一段时间去遍历指定目录的文件,如果此次遍历的结果与上次遍历的结果不同,就认为文件发生了变化。这种方式很繁琐,性能也低。

NIO.2的Path接口提供了一个方法来监听文件变化:

register(WatchService watcher, 要监听的事件类型1,要监听的事件类型2,.......)       //注册一个监听服务

比如“xx安全卫士提醒您:xx程序将创建xx文件,是否允许?”、“xx程序试图修改xx文件,是否允许?”,就可使用此方法实现。

使用示例:

public class Test {
  public static void main(String[] args) throws IOException, InterruptedException {
    //创建一个文件系统的监听服务
    WatchService watchService= FileSystems.getDefault().newWatchService();
    Path path=Paths.get("D:/untitled/test");
    //为该文件夹注册监听,监听新建、修改、删除事件。只能为文件夹(目录)注册监听,不能为单个文件注册监听
    path.register(watchService,StandardWatchEventKinds.ENTRY_CREATE,StandardWatchEventKinds.ENTRY_MODIFY,StandardWatchEventKinds.ENTRY_DELETE);
    //编写事件处理
    while (true){ //一直监听
      //拉取一个WatchKey。当触发监听的事件时,就会产生一个WatchKey,此WatchKey封装了事件信息。
      WatchKey watchKey=watchService.take();
      //使用循环是因为这一个WatchKey中可能有多个文件变化了,比如Ctrl+A全选,然后删除,只触发了一个WatchKey,但有多个文件变化了
      for (WatchEvent event:watchKey.pollEvents()){  
        System.out.println(event.context()+"发生了"+event.kind()+"事件!");
        /*
        watchKey.pollEvents() 获取此次WatchKey中所有变化了的文件的信息,以List(列表)形式返回,一个WatchEvent就是一个元素,封装了一个变化了的文件的信息
        event.context() 获取文件名
        event.kind() 获取发生的事件类型
        因为只能为文件夹注册监听,如果要监听某些指定的文件,可以在增强的for循环中,先根据event.context()判断是否是指定的文件,是才处理。
         */
      }
      //虽然是while()循环,但WatchKey和ByteBuffer一样,使用完要重置状态,才能继续用。
      watchKey.reset();  //如果不重置,WatchKey使用一次过后就不能再使用,即只能监听到一次文件变化。
    }
    /*
    测试:在D:/untitled/test目录下
    1、新建1.txt文件   1.txt.txt发生了ENTRY_CREATE事件!
    2、打开1.txt,输入"hello world!",并保存   1.txt.txt发生了ENTRY_MODIFY事件!
    3、删除“hello world!",并保存   1.txt.txt发生了ENTRY_MODIFY事件!
    4、新建2.txt文件  2.txt发生了ENTRY_CREATE事件!
    说明:编辑文件内容时,不算修改,保存时才算修改。
    5、新建文件夹“图片”
      新建文件夹发生了ENTRY_CREATE事件!
      新建文件夹发生了ENTRY_DELETE事件!
      图片发生了ENTRY_CREATE事件!
    OS执行过程:新建了一个名为“新建文件夹”的文件夹,再把此文件夹重命名为指定的名称。
    重命名时,”新建文件夹“消失了,算作删除,”图片“出现了,算作新建。
    6、在图片目录下,随便新建一个文件或者文件夹
      图片发生了ENTRY_MODIFY事件!
     说明监控的只是子文件、子文件夹,不会递归监控。
    7、全选,删除test下所有文件、子文件夹
      图片发生了ENTRY_DELETE事件!
      1.txt.txt发生了ENTRY_DELETE事件!
      2.txt发生了ENTRY_DELETE事件!
     */
  }
}

拉取一个WatchKey有3种方法:

•WatchKey  take()   //阻塞式拉取,如果未拉取到,会一直等待,直到拉取到一个WatchKey。一般我们用这个。
•WatchKey   poll()   //非阻塞式拉取,试图拉取一个WatchKey,拉取到了就返回拉取的WatchKey对象,没有WatchKey发生就立即返回null。
•WatchKey   poll(long  timeout, TimeUnit  unit)    //非阻塞式拉取,如果没拉取到,会再等待timeout毫秒,还没拉取到才返回null。

总结

以上所述是小编给大家介绍的Java NIO.2 使用Path接口来监听文件、文件夹变化,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

相关文章

  • Java创建型设计模式之单例模式

    Java创建型设计模式之单例模式

    Java单例模式是一种设计模式,它确保一个类只有一个实例,并提供一个全局访问点。可以使用多种方式实现单例模式,如饿汉式、懒汉式、双重检查锁定、静态内部类、枚举等,每种方式都有其优缺点,需要根据具体情况选择使用
    2023-05-05
  • HashMap原理及手写实现部分区块链特征

    HashMap原理及手写实现部分区块链特征

    这篇文章主要为大家介绍了HashMap原理及手写实现部分区块链特征,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • java kafka如何动态设置用户读写权限

    java kafka如何动态设置用户读写权限

    这篇文章主要介绍了java kafka如何动态设置用户读写权限问题,具有很好的参考家价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • java this super使用方法详解

    java this super使用方法详解

    Java中this、super关键字的用法简单说明:super是Java语言的保留字,用来指向类的超类,本文将详细介绍,需要的朋友可以参考下
    2012-12-12
  • System.currentTimeMillis()计算方式与时间的单位转换详解

    System.currentTimeMillis()计算方式与时间的单位转换详解

    这篇文章主要介绍了System.currentTimeMillis()计算方式与时间的单位转换详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • java之swing下拉菜单实现方法

    java之swing下拉菜单实现方法

    这篇文章主要介绍了java之swing下拉菜单实现方法,以实例形式较为详细的分析了基于swing的下拉菜单实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-09-09
  • 详解如何快速定位和解决JSON错误(以Protobuf的JsonFormat.ParseException为例)

    详解如何快速定位和解决JSON错误(以Protobuf的JsonFormat.ParseException为例)

    在开发过程中,JSON数据的解析是一个常见的操作,尤其是在微服务架构中,服务之间的通信通常依赖于JSON格式的数据,然而,JSON数据的格式错误往往会导致解析失败,进而引发系统异常,本文将以一个实际的错误案例为例,详细讲解如何快速定位和解决JSON解析错误
    2025-03-03
  • Springboot3整合Mybatis-plus3.5.3报错问题解决

    Springboot3整合Mybatis-plus3.5.3报错问题解决

    在日常学习springboot3相关的代码时,在使用 SpringBoot3 整合 MyBatisplus 时出现了一些问题,花了不少时间处理,这篇文章主要介绍了Springboot3整合Mybatis-plus3.5.3报错问题解决,需要的朋友可以参考下
    2023-11-11
  • 浅谈一下SpringCloud中Hystrix服务熔断和降级原理

    浅谈一下SpringCloud中Hystrix服务熔断和降级原理

    这篇文章主要介绍了浅谈一下SpringCloud中Hystrix服务熔断和降级原理,Hystrix 是 Netflix 的一款开源的容错框架,通过服务隔离来避免由于依赖延迟、异常,引起资源耗尽导致系统不可用的解决方案,需要的朋友可以参考下
    2023-05-05
  • MybatisPlus代码生成器的使用方法详解

    MybatisPlus代码生成器的使用方法详解

    在这里我将展示如何自动生成实体类、控制层、服务层、mapper等代码,这些基础的代码全部不需要我们手动创建,由MybatisPlus自动帮我们完成,我们只需要告诉MybatisPlus怎么生成这些代码就可以了,在此之前我们需要配置好测试的环境,数据库和表数据 ,需要的朋友可以参考下
    2021-06-06

最新评论