首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 函數式編程(十二):使用 WatchService 監控文件變更

     編輯:Java 相關知識

前言

Java 7 引入 java.nio.file.WatchService,配合 Java 8 Stream API,能以聲明式方式高效監控目錄下的文件創建、修改、刪除事件。本文演示從傳統迴圈遷移到 flatMap() 再到 WatchService 的完整演進。

遞歸列出子目錄文件:從 for 迴圈到 flatMap()

傳統寫法(可變狀態、命令式)

public static void listTheHardWay() {
    List<File> files = new ArrayList<>();
    File[] filesInCurrentDir = new File(".").listFiles();
    for (File file : filesInCurrentDir) {
        File[] filesInSubDir = file.listFiles();
        if (filesInSubDir != null) {
            files.addAll(Arrays.asList(filesInSubDir));
        } else {
            files.add(file);
        }
    }
    System.out.println("Count: " + files.size());
}

函數式寫法:flatMap() 扁平化流

public static void betterWay() {
    List<File> files = Stream.of(new File(".").listFiles())
        .flatMap(file -> file.listFiles() == null ?
            Stream.of(file) : Stream.of(file.listFiles()))
        .collect(Collectors.toList());
    System.out.println("Count: " + files.size());
}

flatMap() 將每個子目錄的文件流「壓扁」合併為單一流,自動處理空目錄(listFiles() == null 視為單元素流),代碼更緊湊且無副作用。

WatchService 監控文件變更

核心步驟

  1. 獲取 Path 並創建 WatchService
  2. 註冊關心的事件類型(ENTRY_CREATE、ENTRY_MODIFY、ENTRY_DELETE)
  3. 輪詢 watchService.poll() 獲取 WatchKey
  4. 遍歷 key.pollEvents() 獲取具體事件上下文

完整示例:監控當前目錄 1 分鐘內的修改事件

Path path = Paths.get(".");
WatchService watchService = path.getFileSystem().newWatchService();
path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);

System.out.println("Report any file changed within next 1 minute...");

WatchKey watchKey = watchService.poll(1, TimeUnit.MINUTES);
if (watchKey != null) {
    watchKey.pollEvents().stream()
        .forEach(event -> System.out.println(event.context()));
}

運行後修改 sample.txt,控制台輸出:

sample.txt

進階技巧

  • 持續監控:將輪詢放入 while (true) 迴圈,處理完事件後 key.reset() 繼續監聽。
  • 過濾特定文件:在 forEach 中用 filter(event -> event.context().toString().endsWith(".properties"))。
  • 併行處理:事件處理耗時長時,提交到線程池異步執行,避免阻塞輪詢。

總結

flatMap() 解決集合扁平化難題,WatchService 提供原生文件系統事件通知。兩者結合 Java 8 函數式 API,讓文件操作代碼既優雅又高效。下一篇將探討閉包與詞法作用域在 Lambda 重用中的應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved