文件系統遍歷是 Java IO 常見需求。本文提供遞歸實現目錄樹打印、文件信息收集的完整代碼,涵蓋層級縮進顯示、文件/目錄區分、數據結構化存儲。
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FilesDemo {
private static final String FILE_PATH = "./";
private static List
|--src
|--main
|--java
|--com
|--example
|--App.java
|--FilesDemo.java
|--test
|--resources
|--config.properties
|--pom.xml
|--README.md
file.listFiles() == null:非目錄或無權限files.length == 0:空目錄// level=1: "|--"
// level=2: " |--"
// level=3: " |--"
public static String getLevelPrefix(int level) {
StringBuilder sb = new StringBuilder();
for (int i = 1; i < level; i++) {
sb.append(" ");
}
sb.append("|--");
return sb.toString();
}
List
Files.walk(Paths.get("."))
.filter(Files::isRegularFile)
.forEach(path -> System.out.println(path));
ForkJoinPool pool = new ForkJoinPool();
pool.submit(() -> Files.walk(Paths.get("."))
.parallel()
.filter(Files::isRegularFile)
.forEach(System.out::println)).get();
// 僅收集 .java 文件
Files.walk(Paths.get("."))
.filter(path -> path.toString().endsWith(".java"))
.forEach(System.out::println);
Files.walkFileTree(Paths.get("."), new SimpleFileVisitor() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
System.err.println("無法訪問: " + file);
return FileVisitResult.CONTINUE;
}
});
| 問題 | 原因 | 解決 |
|---|---|---|
| NullPointerException | file.listFiles() 返回 null | 先判斷 file.isDirectory() 且非 null |
| StackOverflowError | 符號鏈接循環 | 記錄已訪問路徑 Set,檢測循環 |
| 權限拒絕 | 無讀取權限目錄 | try-catch 包裹,記錄錯誤繼續 |
| 中文亂碼 | 文件系統編碼不一致 | 使用 Files API 自動處理編碼 |
遞歸遍歷文件系統代碼簡潔直觀,適合中小型目錄。生產環境大規模遍歷建議使用 Files.walk 併流或訪問者模式,配合異常處理、符號鏈接檢測、編碼自適應,構建健壯的文件系統掃描工具。