files - Watching a Path

本文探讨了使用Java NIO的WatchService来监控文件系统目录变更的方法,通过PathWatcher和TreeWatcher两个示例,展示了如何实时监测并响应文件删除事件,特别是在复杂的目录树结构中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A watchService enables we to set up a process that reacts to changes within a directory. That is, it watches registered objects for changes and events. For example a file manager may use a watch service to monitor a directory for changes so that it can update its display of the list of files when files are created or deleted.

 

// files/PathWatcher.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {ExcludeFromGradle}

import static java.nio.file.StandardWatchEventKinds.*;

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

public class PathWatcher {
  static Path test = Paths.get("test");

  static void delTxtFiles() {
    try {
      Files.walk(test)
          .filter(f -> f.toString().endsWith(".txt")) // must be f.toString()
          .forEach(
              f -> {
                try {
                  System.out.println("deleting " + f);
                  Files.delete(f);
                } catch (IOException e) {
                  throw new RuntimeException(e);
                }
              });
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  public static void main(String[] args) throws Exception {
    Directories.refreshTestDir();
    Directories.populateTestDir();
    System.out.println("test:" + test);
    Files.createFile(test.resolve("Hello.txt"));
    WatchService watcher = FileSystems.getDefault().newWatchService();
    test.register(watcher, ENTRY_DELETE);
    Executors.newSingleThreadScheduledExecutor()
        .schedule(PathWatcher::delTxtFiles, 250, TimeUnit.MILLISECONDS);
    WatchKey key = watcher.take();
    for (WatchEvent evt : key.pollEvents()) {
      System.out.println(
          "evt.context(): "
              + evt.context()
              + "\nevt.count(): "
              + evt.count()
              + "\nevt.kind(): "
              + evt.kind());
      System.exit(0);
    }
  }
}
/* My Output:
test:test
deleting test/foo/bar/baz/bag/File.txt
deleting test/baz/bag/foo/bar/File.txt
deleting test/bar/baz/bag/foo/File.txt
deleting test/bag/foo/bar/baz/File.txt
deleting test/Hello.txt
*/

schedule

public <V> ScheduledFuture<V> schedule(Callable<V> callable,
                                       long delay,
                                       TimeUnit unit)

Description copied from interface: ScheduledExecutorService

Creates and executes a ScheduledFuture that becomes enabled after the given delay.

Specified by:

schedule in interface ScheduledExecutorService

Type Parameters:

V - the type of the callable's result

Parameters:

callable - the function to execute

delay - the time from now to delay execution

unit - the time unit of the delay parameter

Returns:

a ScheduledFuture that can be used to extract result or cancel

Throws:

RejectedExecutionException - if the task cannot be scheduled for execution

NullPointerException - if callable is null

 

take

WatchKey take()
       throws InterruptedException

Retrieves and removes next watch key, waiting if none are yet present.

Returns:

the next watch key

Throws:

ClosedWatchServiceException - if this watch service is closed, or it is closed while waiting for the next key

InterruptedException - if interrupted while waiting

 

// files/TreeWatcher.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {ExcludeFromGradle}

import static java.nio.file.StandardWatchEventKinds.*;

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

public class TreeWatcher {
  static void watchDir(Path dir) {
    try {
      WatchService watcher = FileSystems.getDefault().newWatchService();
      dir.register(watcher, ENTRY_DELETE);
      Executors.newSingleThreadExecutor()
          .submit(
              () -> {
                try {
                  WatchKey key = watcher.take();
                  for (WatchEvent evt : key.pollEvents()) {
                    System.out.println(
                        "evt.context(): "
                            + evt.context()
                            + "\nevt.count(): "
                            + evt.count()
                            + "\nevt.kind(): "
                            + evt.kind());
                    System.exit(0);
                  }
                } catch (InterruptedException e) {
                  return;
                }
              });
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  public static void main(String[] args) throws Exception {
    Directories.refreshTestDir();
    Directories.populateTestDir();
    Files.walk(Paths.get("test")).filter(Files::isDirectory).forEach(TreeWatcher::watchDir);
    PathWatcher.delTxtFiles();
  }
}
/* My Output:
deleting test/foo/bar/baz/bag/File.txt
deleting test/baz/bag/foo/bar/File.txt
deleting test/bar/baz/bag/foo/File.txt
deleting test/bag/foo/bar/baz/File.txt
evt.context(): File.txt
evt.count(): 1
evt.kind(): ENTRY_DELETE
*/

references:

1. On Java 8 - Bruce Eckel

2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/files/PathWatcher.java

3. https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html#schedule-java.util.concurrent.Callable-long-java.util.concurrent.TimeUnit-

4. https://docs.oracle.com/javase/8/docs/api/java/nio/file/WatchService.html

5. https://blog.youkuaiyun.com/wangbingfengf98/article/details/89425199

6. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/files/TreeWatcher.java

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值