Java实现监听文件变化的三种方案详解

Java实现监听文件变化的三种方案详解

在Java编程中,经常需要对文件进行监听,以便在文件发生更新时及时做出相应的处理。下面将介绍三种实现文件监听的方案,分别是Java 7的WatchService、commons-io库、以及第三方库jnotify。

1. Java 7的WatchService

Java 7引入了WatchService API,它可以用来监听文件目录中的所有变化,包括文件的创建、修改、删除、重命名等。下面是基本的WatchService示例:

import java.io.*;
import java.nio.file.*;

public class FileWatcherTest {

    public static void main(String[] args) throws IOException, InterruptedException {

        WatchService watcher = FileSystems.getDefault().newWatchService();
        Path dir = Paths.get("/Users/username/test/");
        dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,  
        StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);

        while (true) {
            WatchKey key;
            try {
                key = watcher.take();
            } catch (InterruptedException ex) {
                return;
            }

            for (WatchEvent<?> event : key.pollEvents()) {
                WatchEvent.Kind<?> kind = event.kind();

                if (kind == StandardWatchEventKinds.OVERFLOW) {
                    continue;
                }

                WatchEvent<Path> e = (WatchEvent<Path>)event;
                Path filename = e.context();

                // 打印出文件变化事件类型和文件名
                System.out.println(kind + " -> " + filename);
            }

            boolean valid = key.reset();
            if (!valid) {
                break;
            }
        }
    }
}

上述代码将监听指定目录(/Users/username/test/)中所有文件的创建、修改、删除事件,并且当这些事件发生时,会打印出事件类型和文件名。在这个示例中,我们使用了WatchService的take()方法来阻塞等待事件的发生,一旦事件发生即会被唤醒。

2. commons-io库

Apache Commons IO库提供了一个监视器(FileMonitor)类,可以监听指定目录中的文件变化。这个监视器在后台运行,可以周期性地扫描指定的目录,并且对发生变化的文件会回调一个指定的监听器类。

下面是一个简单的示例,演示了如何监听指定目录中所有的txt文件:

import org.apache.commons.io.monitor.*;
import java.io.*;

public class MonitorTest {
    public static void main(String[] args) throws Exception {
        File folder = new File("/Users/username/test/");   
        FileAlterationObserver observer = new FileAlterationObserver(folder);

        // 过滤规则,只对txt文件进行监听           
        FileFilter filter = FileFilterUtils.suffixFileFilter(".txt"); 
        observer.setFileFilter(filter);    

        // 监听器
        FileAlterationListener listener = new FileAlterationListenerAdaptor() {
            public void onFileCreate(File file) {
                System.out.println("File created: " + file.getAbsolutePath());
            }

            public void onFileChange(File file) {
                System.out.println("File changed: " + file.getAbsolutePath());
            }

            public void onFileDelete(File file) {
                System.out.println("File deleted: " + file.getAbsolutePath());
            }
        };

        observer.addListener(listener);

        // 开始监听
        FileAlterationMonitor monitor = new FileAlterationMonitor(5000); // 5秒扫描一次
        monitor.addObserver(observer);
        monitor.start();
    }
}

上述代码使用了FileAlterationObserver类来监控指定目录文件的变化,添加了过滤规则只监听指定后缀名的txt文件,实现了三种事件回调的方法。代码中使用了FileAlterationMonitor来启动监控进程,每隔5秒监听一次文件变化。

3. jnotify

jnotify是一个跨平台的文件系统监听库,为JVM提供了更高效、更可靠的文件监控机制。jnotify需要本地库的支持,所以使用前需要根据操作系统的不同下载对应的jni实现,并引用库文件。

下面是jnotify的一个示例,演示了如何监听指定目录中所有的txt文件:

import net.contentobjects.jnotify.*;

public class JNotifyTest {
    public static void main(String[] args) throws Exception {
        String path = "/Users/username/test/";

        JNotify.addWatch(path, 
            JNotify.FILE_CREATED, 
            JNotify.FILE_DELETED, 
            JNotify.FILE_MODIFIED, 
            JNotify.FILE_RENAMED);

        JNotifyListener listener = new JNotifyListener() {
            public void fileRenamed(int wd, String rootPath, String oldName, String newName) {
                System.out.println("File renamed: " + oldName + " -> " + newName);
            }

            public void fileModified(int wd, String rootPath, String name) {
                System.out.println("File modified: " + name);
            }

            public void fileDeleted(int wd, String rootPath, String name) {
                System.out.println("File deleted: " + name);
            }

            public void fileCreated(int wd, String rootPath, String name) {
                System.out.println("File created: " + name);
            }
        };

        // 开始监听
        int watchId = JNotify.addWatch(path, JNotify.FILE_ANY, true, listener);

        // 等待事件
        Thread.sleep(1000000);

        // 删除监听
        boolean res = JNotify.removeWatch(watchId);
        if (!res) {
            System.out.println("Error removing watch");
        }
    }
}

上述代码使用了jnotify的addWatch()方法来添加对指定目录的监听,指定了四种事件类型,并且实现了指定路径下发生变化回调的listener。在示例中,我们等待1000000毫秒,让程序一直监听文件变化,当监听到变化时将输出事件类型和文件名。在示例结束后,我们使用jnotify的removeWatch()方法来终止监听。

以上是三种实现文件监听的方法,各有其优缺点,可以根据具体需求选择适当的方法。在实际项目中,我们可以根据文件系统的特点和自身业务逻辑的需求来选择最适合的方案。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现监听文件变化的三种方案详解 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • JSP 中Servlet的自己实现

    JSP 中Servlet的自己实现 Servlet是Java中常用的服务器端程序,可以接收和处理HTTP请求,并返回相应的 HTTP响应。JSP(Java Server Pages) 是一个动态的Java web页面技术,可以在网页中嵌入 Java 代码片段,用于生成动态内容。 在JSP中使用Servlet,通常有两种方式:一是在JSP页面中直接使用标签引入…

    Java 2023年6月15日
    00
  • Java中的StackOverflowError是什么?

    Java中的StackOverflowError是一种运行时异常,表示在程序运行中调用了过多的方法导致方法调用栈溢出。 在Java中,每个方法的调用会在堆栈中创建一个称为“栈帧”的内存区域,该区域用于存储方法调用的参数、局部变量和返回地址等信息。当程序调用嵌套方法时,每个方法的栈帧将被逐个压入栈中。当方法返回时,其栈帧将被弹出并释放以供下次使用。如果堆栈不能…

    Java 2023年4月27日
    00
  • 基于编译虚拟机jvm—openjdk的编译详解

    基于编译虚拟机jvm—openjdk的编译详解 在这篇攻略中,我们将通过使用编译虚拟机jvm-openjdk来编译代码。下面是详细的步骤: 步骤一:安装OpenJDK 在使用OpenJDK编译代码之前,我们需要先安装它。在Linux系统中,我们可以通过以下命令来安装OpenJDK: sudo apt-get install default-jdk 在Wind…

    Java 2023年5月26日
    00
  • Mybatis中注入执行sql查询、更新、新增及建表语句案例代码

    让我来为你讲解Mybatis中注入执行SQL查询、更新、新增及建表语句的完整攻略。 什么是Mybatis? Mybatis是一个Java持久化框架,它可以帮助我们将Java对象与关系型数据库之间建立映射关系,同时提供了大量的查询、更新、新增和删除数据的API。 Mybatis支持多种ORM(对象关系映射)方式,其中比较常用的是注解和XML配置文件。本文将主要…

    Java 2023年5月20日
    00
  • 使用@Valid+BindingResult进行controller参数校验方式

    当我们在编写Spring MVC应用程序时,通常需要对传递给控制器方法的参数进行验证。这可以确保我们的应用程序不会因为无效数据而崩溃或出现意外行为。Spring提供了一种简单而强大的机制来执行这些验证操作 – 使用@Valid注释。 在使用@Valid进行校验时,我们需要与BindingResult参数结合使用。BindingResult提供了与校验相关的各…

    Java 2023年5月20日
    00
  • Java中常用的Lambda表达式案例解析

    首先我们来介绍Lambda表达式。Lambda表达式是Java 8中引入的新特性,可以使得代码更加简洁、易读、易维护、可重用性更高,是一种将行为作为方法参数传递的方法。Lambda表达式由参数、箭头和函数体组成,语法结构如下: (parameter1, parameter2, …) -> { // 参数列表,可以为空,如果不为空则必须要使用括号 // …

    Java 2023年5月26日
    00
  • Java虚拟机JVM之server模式与client模式的区别

    Java虚拟机JVM之server模式与client模式的区别 1. 背景 在Java应用程序执行过程中,Java虚拟机(JVM)是一个关键的组件,负责将Java字节码解释成可执行的机器指令。为了提高应用程序的性能,JVM提供了不同的启动模式来适应不同的运行环境。 JVM支持两种启动模式:client模式和server模式。本文将详细讲解这两种启动模式之间的…

    Java 2023年5月26日
    00
  • Java下使用Oracle存储过程(详解)第3/3页

    下面是详细讲解“Java下使用Oracle存储过程(详解)第3/3页”的完整攻略。 1. 概述 这篇攻略主要介绍如何在Java中使用Oracle存储过程。存储过程是一组一起执行的SQL语句,可以接收参数并返回结果。在一些大型应用中,存储过程的使用可以提高数据库性能,减小网络传输压力,增加数据安全等等。 2. 实现步骤 步骤如下: (1)创建存储过程 首先在O…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部