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日

相关文章

  • 关于Mybatis与JPA的优缺点说明

    下面给出“关于Mybatis与JPA的优缺点说明”的完整攻略。 一、Mybatis与JPA的介绍 Mybatis Mybatis 是一款优秀的开源持久层框架,支持基本的 CRUD 操作,可以自定义SQL查询语句,可以完全掌控 SQL 的编写过程;同时也支持防止 SQL 注入攻击等功能。 JPA JPA(Java Persistence API)是 Java …

    Java 2023年5月20日
    00
  • SpringBoot自定义cron表达式注册定时任务

    springBoot自定义cron表达式注册定时任务 一、原理 1、使用Spring自带的TaskScheduler注册任务 2、注册后返回:ScheduledFuture,用于取消定时任务 3、注册任务后不会马上取消任务,所以将任务缓存。在需要取消任务的时候调用取消接口取消 4、cron表达式可以由前端或者后端生成。实现中会校验cron表达式 public…

    Java 2023年4月22日
    00
  • 解决Tomcat启动报异常java.lang.ClassNotFoundException问题

    下面是解决Tomcat启动报异常java.lang.ClassNotFoundException问题的完整攻略。 问题背景 在使用Tomcat启动项目时,有时候会出现java.lang.ClassNotFoundException异常,这是因为Tomcat无法找到相关的类文件。在这种情况下,需要进一步排查问题并解决它。 解决方法 1. 检查类路径 首先,需要…

    Java 2023年5月19日
    00
  • SpringBoot详解如果通过@Value注解给静态变量注入值

    下面为您详细讲解“Spring Boot通过@Value注解给静态变量注入值”的攻略。 背景介绍 在Spring Boot开发中,我们通常使用@ConfigurationProperties注解来为Java Bean注入外部配置属性。但是,如果我们需要为静态变量注入外部属性,就需要使用@Value注解。 示例 示例1:注入基本数据类型 首先,让我们看一个简单…

    Java 2023年5月20日
    00
  • Java对象深复制与浅复制实例详解

    Java对象深复制与浅复制实例详解 在 Java 中,对象的复制分为浅复制和深复制两种方式。本文将详细讲解 Java 中对象复制的概念、浅复制和深复制的实现方式、以及深浅复制的应用场景。 对象复制的概念 在 Java 中,我们可以通过 new 运算符来生成新的对象实例,但是有时候我们需要创建一个新对象,它的属性和原对象一模一样而且它们内存地址不同,这个时候就…

    Java 2023年5月26日
    00
  • Java 关于时间复杂度和空间复杂度的深度刨析

    Java 关于时间复杂度和空间复杂度的深度刨析 时间复杂度和空间复杂度是算法中非常重要的概念,它们可以帮助我们衡量算法的效率。本文将对它们进行深度探讨,并用实例进行说明。 时间复杂度 时间复杂度是指算法执行所需要的时间,通常使用O(n)表示,其中n是输入数据的规模。常见的时间复杂度有: 常数时间复杂度:O(1),无论输入数据量的大小,算法的执行时间都保持不变…

    Java 2023年5月26日
    00
  • 作为Java程序员应该掌握的10项技能

    作为Java程序员,掌握以下10项技能是非常重要的: 1. 熟悉Java基础知识 Java是一种面向对象的编程语言,因此对于Java程序员来说,熟悉Java基础知识是非常重要的。这包括变量、数据类型、循环、条件语句、方法、类、对象等。 示例: public class Main { public static void main(String[] args)…

    Java 2023年5月20日
    00
  • JavaEE简介_动力节点Java学院整理

    JavaEE简介_动力节点Java学院整理 JavaEE(Java Enterprise Edition)是Java SE(Java Standard Edition)的扩展,旨在为企业级应用程序提供支持。其包含许多不同的规范和技术,用于开发和部署企业应用程序。JavaEE应用程序通常运行在JavaEE兼容的应用服务器上,并具有高可用性、可伸缩性和安全性的特…

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