讲师中心 微信公众号

工具推荐

视频效率加速
Seko
Seko

AI短剧一键生成成片

updream

一键生成高质量推广成片

剧云
剧云

中文短剧剧本制作平台

AniShort
AniShort

AI短剧协同制作平台

Java 文件读写中 WatchService 中 ENTRY_CREATE 怎么使用

阿瑶小哥_6667

阿瑶小哥_6667

发布时间:2026-11-13 11:39:10

|

996人浏览过

|

来源于php中文网

原创

在 java 文件读写中,使用 watchservice 的 entry_create 事件需要调用 register() 方法并传入 standardwatcheventkinds.entry_create 常量。该操作会向操作系统注册一个目录监听器,当指定目录下出现新文件或子目录时,系统会触发此事件,开发者需在循环中通过 pollevents() 获取事件对象并进行处理。

Java 文件读写中 WatchService 中 ENTRY_CREATE 怎么使用

如何正确注册 ENTRY_CREATE 事件到 WatchService

要注册 ENTRY_CREATE 事件,必须创建一个 WatchService 实例,然后调用目标 Path 对象的 register() 方法。该方法接受两个参数:第一个是 WatchEvent.Kind> 类型的枚举值,即 StandardWatchEventKinds.ENTRY_CREATE;第二个是可选的事件修饰符(如 AT_MOST_ONCE)。注册成功后,任何在该路径下创建的新条目都会产生一个 WatchEvent 对象,其上下文(context)即为新创建的文件或目录的名称。

Java 文件读写中 WatchService 中 ENTRY_CREATE 怎么使用

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

public class FileWatcher {
    public static void main(String[] args) throws IOException, InterruptedException {
        // 1. 创建 WatchService
        WatchService watchService = FileSystems.getDefault().newWatchService();
        
        // 2. 定义要监听的目录路径
        Path path = Paths.get("./test_dir");
        
        // 3. 注册 ENTRY_CREATE 事件
        // 注意:如果目录不存在,register() 会抛出 NoSuchFileException
        if (Files.exists(path)) {
            watchService.register(path, StandardWatchEventKinds.ENTRY_CREATE);
            System.out.println("开始监听目录: " + path);
            
            while (true) {
                // 4. 阻塞等待事件
                WatchKey key = watchService.take();
                for (WatchEvent<?> event : key.pollEvents()) {
                    WatchEvent.Kind<?> kind = event.kind();
                    
                    // 5. 检查是否为 ENTRY_CREATE
                    if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
                        @SuppressWarnings("unchecked")
                        WatchEvent<Path> pathEvent = (WatchEvent<Path>) event;
                        Path fileName = pathEvent.context();
                        System.out.println("检测到新创建的文件/目录: " + fileName);
                        
                        // 实际业务逻辑:例如读取新文件内容
                        Path fullPath = path.resolve(fileName);
                        if (Files.isRegularFile(fullPath)) {
                            System.out.println("新文件内容预览: " + Files.readString(fullPath));
                        }
                    }
                }
                // 6. 重置 Key 以便继续接收后续事件
                boolean valid = key.reset();
                if (!valid) {
                    break;
                }
            }
        } else {
            System.err.println("监听目录不存在");
        }
    }
}

上述代码展示了完整的监听流程。首先通过 FileSystems.getDefault().newWatchService() 获取服务实例。接着,确保监听路径存在后,调用 path.register() 并将 StandardWatchEventKinds.ENTRY_CREATE 作为参数传入。在无限循环中,watchService.take() 会阻塞直到有事件发生。获取到 WatchKey 后,遍历其包含的所有 WatchEvent。通过判断 event.kind() 是否等于 ENTRY_CREATE,可以过滤出创建事件。此时,event.context() 返回的是新条目的相对路径名(Path 类型),结合原始监听路径即可得到完整路径进行后续操作。最后务必调用 key.reset(),否则该 WatchKey 将失效,不再接收新事件。

立即学习“Java免费学习笔记(深入)”;

JavaScript 开发专家
JavaScript 开发专家

掌握包含 ES6+、异步模式和 Node.js API 的现代 JavaScript。处理 Promise、事件循环和浏览器/Node 兼容性。在 JavaSc

下载

ENTRY_CREATE 与 ENTRY_MODIFY 的区别及适用场景

ENTRY_CREATE 仅在文件或目录被首次创建时触发一次,而 ENTRY_MODIFY 则在文件内容修改、属性更改或元数据更新时持续触发。若需监控日志文件的实时追加写入,应使用 ENTRY_MODIFY;若需监控用户上传目录以自动处理新上传的文件,则应使用 ENTRY_CREATE。两者可同时在同一个 register() 调用中注册,以同时捕获创建和修改行为。

Java 文件读写中 WatchService 中 ENTRY_CREATE 怎么使用

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

public class DualEventWatcher {
    public static void main(String[] args) throws IOException, InterruptedException {
        WatchService watchService = FileSystems.getDefault().newWatchService();
        Path path = Paths.get("./data_dir");
        
        // 同时注册 CREATE 和 MODIFY 事件
        watchService.register(path, 
            StandardWatchEventKinds.ENTRY_CREATE,
            StandardWatchEventKinds.ENTRY_MODIFY
        );
        
        while (true) {
            WatchKey key = watchService.take();
            for (WatchEvent<?> event : key.pollEvents()) {
                WatchEvent.Kind<?> kind = event.kind();
                String eventType = (kind == StandardWatchEventKinds.ENTRY_CREATE) ? "CREATE" : "MODIFY";
                
                @SuppressWarnings("unchecked")
                WatchEvent<Path> pathEvent = (WatchEvent<Path>) event;
                Path fileName = pathEvent.context();
                
                System.out.println("[" + eventType + "] 文件变化: " + fileName);
                
                // 如果是 MODIFY,可能需要重新读取文件以获取最新内容
                if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
                    Path fullPath = path.resolve(fileName);
                    if (Files.exists(fullPath) && Files.isRegularFile(fullPath)) {
                        System.out.println("当前文件大小: " + Files.size(fullPath) + " bytes");
                    }
                }
            }
            key.reset();
        }
    }
}

在实际应用中,区分这两种事件至关重要。ENTRY_CREATE 适用于一次性初始化场景,例如当新配置文件出现时加载其内容。而 ENTRY_MODIFY 适用于流式数据处理,例如监控 CSV 文件的追加写入。在上面的双事件监听示例中,程序同时注册了两种事件。当检测到 ENTRY_MODIFY 时,代码会检查文件大小,因为修改事件可能由截断、覆盖或追加引起,仅靠事件本身无法得知具体变更内容,通常需要结合文件状态判断。这种组合注册方式允许开发者在一个轮询循环中统一处理不同类型的文件系统变更,简化了并发控制逻辑。

如何处理 ENTRY_CREATE 事件中的空指针或无效路径问题

在处理 ENTRY_CREATE 事件时,event.context() 返回的 Path 对象可能指向一个尚未完全初始化的临时文件,或者在极快连续创建的情况下出现竞态条件。直接访问该路径可能导致 NoSuchFileException 或 AccessDeniedException。最佳实践是在执行具体业务逻辑前,先使用 Files.exists() 和 Files.isRegularFile() 进行双重校验,并配合重试机制或短暂延迟来确保文件系统状态稳定。

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

public class SafeCreateHandler {
    public static void main(String[] args) throws IOException, InterruptedException {
        WatchService watchService = FileSystems.getDefault().newWatchService();
        Path path = Paths.get("./safe_dir");
        watchService.register(path, StandardWatchEventKinds.ENTRY_CREATE);
        
        while (true) {
            WatchKey key = watchService.take();
            for (WatchEvent<?> event : key.pollEvents()) {
                if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
                    @SuppressWarnings("unchecked")
                    WatchEvent<Path> pathEvent = (WatchEvent<Path>) event;
                    Path newFile = path.resolve(pathEvent.context());
                    
                    // 安全处理:检查文件是否存在且为普通文件
                    if (Files.exists(newFile) && Files.isRegularFile(newFile)) {
                        try {
                            // 尝试读取,若失败则忽略或记录日志
                            String content = Files.readString(newFile);
                            System.out.println("成功读取新文件: " + newFile.getFileName());
                        } catch (IOException e) {
                            System.err.println("读取文件失败,可能正在写入中: " + e.getMessage());
                        }
                    } else {
                        System.out.println("文件尚不可用或为目录: " + newFile.getFileName());
                    }
                }
            }
            key.reset();
        }
    }
}

由于操作系统对文件创建的原子性保证在不同平台上表现不同,某些情况下 ENTRY_CREATE 触发时文件句柄可能仍被创建进程占用,导致立即读取失败。因此,在代码中加入 Files.exists() 检查是必要的防御性编程步骤。此外,对于大型文件,建议在检测到存在后增加短暂的 Thread.sleep() 或使用轮询重试,以确保文件写入完成。这种处理方式避免了因文件系统状态不一致导致的运行时异常,确保了监听服务的稳定性。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

12517

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

9602

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

8172

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1324

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1048

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

1576

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

3289

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

20511

2023.08.03

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn