import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class FileWalker {
/** 遞歸收集指定目錄下所有檔案絕對路徑 */
public static List<String> listAllFiles(String directoryPath) {
List<String> result = new ArrayList<>();
File root = new File(directoryPath);
collect(root, result);
return result;
}
private static void collect(File file, List<String> result) {
if (!file.exists() || !file.isDirectory()) {
return; // 不存在或非目錄
}
File[] children = file.listFiles();
if (children == null) return; // IO 錯誤或權限不足
for (File child : children) {
if (child.isDirectory()) {
collect(child, result); // 遞歸進入子目錄
} else {
result.add(child.getAbsolutePath()); // 收集檔案
}
}
}
}
public static void main(String[] args) {
String path = "D:/Projects";
List<String> files = FileWalker.listAllFiles(path);
System.out.println("共找到 " + files.size() + " 個檔案:");
files.forEach(System.out::println);
}
import java.nio.file.*;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
public class ModernFileWalker {
public static List<String> walk(String dir) throws IOException {
try (Stream<Path> stream = Files.walk(Paths.get(dir))) {
return stream
.filter(Files::isRegularFile) // 只保留檔案,排除目錄
.map(Path::toAbsolutePath)
.map(Path::toString)
.collect(Collectors.toList());
}
}
// 限制深度
public static List<String> walkMaxDepth(String dir, int maxDepth) throws IOException {
try (Stream<Path> stream = Files.walk(Paths.get(dir), maxDepth)) {
return stream.filter(Files::isRegularFile)
.map(Path::toString).collect(Collectors.toList());
}
}
}
// 只收集 .java 檔案,且大小 > 1KB
Files.walk(Paths.get(dir))
.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".java"))
.filter(p -> {
try { return Files.size(p) > 1024; }
catch (IOException e) { return false; }
})
.forEach(System.out::println);
// 處理海量檔案避免記憶體爆炸:使用 forEach 而非 collect
Files.walk(Paths.get(dir))
.filter(Files::isRegularFile)
.forEach(path -> processFile(path)); // 串流處理,不累積 List
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 遞歸 File.listFiles() | 相容舊版 Java、邏輯直觀 | 深層目錄棧溢位、無法中斷、效能一般 | Java 6 維護專案、簡單腳本 |
| Files.walk() Stream | 函數式、可並行、支援過濾/限制深度 | 需 Java 7+、大量檔案 collect 佔記憶體 | 現代專案首選 |
| Files.walkFileTree() | 完全控制 (可跳過、繼續、異常處理) | 代碼較繁瑣 | 需自定義訪問邏輯、刪除目錄樹 |
Files.walk 預設不跟隨符號連結,避免無限循環listFiles() 返回 null,需判空;NIO 拋 AccessDeniedException,需 try-catch\\?\ 前綴!Files.isHidden(p)現代 Java 專案**首選 Files.walk() Stream API**,代碼簡潔、支援函數式過濾、易於並行化。舊版專案或簡單腳本可用遞歸 File.listFiles(),注意判空與棧深度。處理超大目錄樹時,使用 forEach 串流處理避免記憶體壓力。