Java 7 引入 java.nio.file.WatchService,配合 Java 8 Stream API,能以聲明式方式高效監控目錄下的文件創建、修改、刪除事件。本文演示從傳統迴圈遷移到 flatMap() 再到 WatchService 的完整演進。
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());
}
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 視為單元素流),代碼更緊湊且無副作用。
Path 並創建 WatchServiceENTRY_CREATE、ENTRY_MODIFY、ENTRY_DELETE)watchService.poll() 獲取 WatchKeykey.pollEvents() 獲取具體事件上下文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 重用中的應用。