Java实现实时监控目录下文件变化的方法

 更新时间:2019年03月15日 09:17:41   作者:梦幻逝水  
今天小编就为大家分享一篇关于Java实现实时监控目录下文件变化的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

一、commons-io方法

1、使用Commons-io的monitor下的相关类可以处理对文件进行监控,它采用的是观察者模式来实现的

  • (1)可以监控文件夹的创建、删除和修改
  • (2)可以监控文件的创建、删除和修改
  • (3)采用的是观察者模式来实现的
  • (4)采用线程去定时去刷新检测文件的变化情况

2、引入commons-io包,需要2.0以上。

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.6</version>
</dependency>

3、编写继承FileAlterationListenerAdaptor的类FileListener。

import java.io.File;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.apache.log4j.Logger;
/**
 * 文件变化监听器
 * 在Apache的Commons-IO中有关于文件的监控功能的代码. 文件监控的原理如下:
 * 由文件监控类FileAlterationMonitor中的线程不停的扫描文件观察器FileAlterationObserver,
 * 如果有文件的变化,则根据相关的文件比较器,判断文件时新增,还是删除,还是更改。(默认为1000毫秒执行一次扫描)
 */
public class FileListener extends FileAlterationListenerAdaptor {
  private Logger log = Logger.getLogger(FileListener.class);
  /**
   * 文件创建执行
   */
  public void onFileCreate(File file) {
    log.info("[新建]:" + file.getAbsolutePath());
  }
  /**
   * 文件创建修改
   */
  public void onFileChange(File file) {
    log.info("[修改]:" + file.getAbsolutePath());
  }
  /**
   * 文件删除
   */
  public void onFileDelete(File file) {
    log.info("[删除]:" + file.getAbsolutePath());
  }
  /**
   * 目录创建
   */
  public void onDirectoryCreate(File directory) {
    log.info("[新建]:" + directory.getAbsolutePath());
  }
  /**
   * 目录修改
   */
  public void onDirectoryChange(File directory) {
    log.info("[修改]:" + directory.getAbsolutePath());
  }
  /**
   * 目录删除
   */
  public void onDirectoryDelete(File directory) {
    log.info("[删除]:" + directory.getAbsolutePath());
  }
  public void onStart(FileAlterationObserver observer) {
    // TODO Auto-generated method stub
    super.onStart(observer);
  }
  public void onStop(FileAlterationObserver observer) {
    // TODO Auto-generated method stub
    super.onStop(observer);
  }
}

4、实现main方法

public static void main(String[] args) throws Exception{
    // 监控目录
    String rootDir = "D:\\apache-tomcat-7.0.78";
    // 轮询间隔 5 秒
    long interval = TimeUnit.SECONDS.toMillis(1);
    // 创建过滤器
    IOFileFilter directories = FileFilterUtils.and(
        FileFilterUtils.directoryFileFilter(),
        HiddenFileFilter.VISIBLE);
    IOFileFilter files    = FileFilterUtils.and(
        FileFilterUtils.fileFileFilter(),
        FileFilterUtils.suffixFileFilter(".txt"));
    IOFileFilter filter = FileFilterUtils.or(directories, files);
    // 使用过滤器
    FileAlterationObserver observer = new FileAlterationObserver(new File(rootDir), filter);
    //不使用过滤器
    //FileAlterationObserver observer = new FileAlterationObserver(new File(rootDir));
    observer.addListener(new FileListener());
    //创建文件变化监听器
    FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
    // 开始监控
    monitor.start();
  }

二、使用JDK7提供的WatchService

public static void main(String[] a) {
    final Path path = Paths.get("D:\\apache-tomcat-7.0.78");
    try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
      //给path路径加上文件观察服务
      path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
          StandardWatchEventKinds.ENTRY_MODIFY,
          StandardWatchEventKinds.ENTRY_DELETE);
      while (true) {
        final WatchKey key = watchService.take();
        for (WatchEvent<?> watchEvent : key.pollEvents()) {
          final WatchEvent.Kind<?> kind = watchEvent.kind();
          if (kind == StandardWatchEventKinds.OVERFLOW) {
            continue;
          }
          //创建事件
          if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
            System.out.println("[新建]");
          }
          //修改事件
          if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
            System.out.println("修改]");
          }
          //删除事件
          if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
            System.out.println("[删除]");
          }
          // get the filename for the event
          final WatchEvent<Path> watchEventPath = (WatchEvent<Path>) watchEvent;
          final Path filename = watchEventPath.context();
          // print it out
          System.out.println(kind + " -> " + filename);
        }
        boolean valid = key.reset();
        if (!valid) {
          break;
        }
      }
    } catch (IOException | InterruptedException ex) {
      System.err.println(ex);
    }
  }

三、以上方法都可以实现对相应文件夹得文件监控,但是在使用jdk7提供的API时,会出现些许问题。

  • (1)当文件修改时,会被调用两次,即输出两个相同的修改。
  • (2)不能对其子文件夹进行监控,只能提示目录被修改。
  • (3)无法对文件类型进行过滤。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • Windows系统下JDK1.8与JDK11版本切换超详细教程

    Windows系统下JDK1.8与JDK11版本切换超详细教程

    这篇文章主要给大家介绍了关于Windows系统下JDK1.8与JDK11版本切换的超详细教程,我们可以有多个工程项目,用的JDK版本不一样,这个时候就需要进行自由切换JDK版本了,需要的朋友可以参考下
    2023-07-07
  • Java StampedLock实现原理与最佳实践记录

    Java StampedLock实现原理与最佳实践记录

    本文介绍了Java 8引入的StampedLock,这是一种多模式同步控制组件,通过“戳”(stamp)标识锁的状态,支持写锁、悲观读锁和乐观读三种模式,StampedLock在特定场景下能够大幅提升系统性能,特别是在读多写少的场景中,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • Java Web项目中使用Socket通信多线程、长连接的方法

    Java Web项目中使用Socket通信多线程、长连接的方法

    很多时候在javaweb项目中我们需要用到Socket通信来实现功能,在web中使用Socket我们需要建立一个监听程序,在程序启动时,启动socket监听。接下来通过本文给大家介绍Java Web项目中使用Socket通信多线程、长连接的方法,感兴趣的朋友一起学习
    2016-04-04
  • Java对数组实现选择排序算法的实例详解

    Java对数组实现选择排序算法的实例详解

    这篇文章主要介绍了Java对数组实现选择排序算法的实例,选择排序的比较次数为 O(N^2)而交换数为O(N),需要的朋友可以参考下
    2016-04-04
  • springcloud之自定义简易消费服务组件

    springcloud之自定义简易消费服务组件

    这篇文章主要介绍了springcloud之自定义简易消费服务组件,本篇来使用rest+ribbon消费服务,并且通过轮询方式来自定义了个简易消费组件,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • Java通过反射查看类的信息示例

    Java通过反射查看类的信息示例

    这篇文章主要介绍了Java通过反射查看类的信息,结合实例形式详细分析了java基于反射获取类信息的相关原理与实现技巧,需要的朋友可以参考下
    2019-07-07
  • 解决idea不支持SpringBoot yml文件的图文教程

    解决idea不支持SpringBoot yml文件的图文教程

    这篇文章主要介绍了解决idea不支持SpringBoot yml文件,需要的朋友可以参考下
    2018-06-06
  • 一文详解Java中的包装类和泛型

    一文详解Java中的包装类和泛型

    在Java中,由于基本类型不是继承⾃Object,为了在泛型中可以⽀持基本类型,Java给每个基本类型都对应了⼀个包装类型,有些情况下只有接收泛型才可以完成其功能,所以本文将给大家详细讲解一下Java中的包装类和泛型,需要的朋友可以参考下
    2025-04-04
  • 深入了解Java对象的克隆

    深入了解Java对象的克隆

    这篇文章主要介绍了Java对象的克隆的相关资料,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-08-08
  • 启动Spring项目详细过程(小结)

    启动Spring项目详细过程(小结)

    这篇文章主要介绍了启动Spring项目详细过程(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11

最新评论