在 Java 開發中,遞歸遍歷目錄以獲取所有文件列表是常見需求。本文提供一個健壯、可排序的完整實現方案,包含目錄驗證、遞歸遍歷與結果排序,適合直接集成到項目中使用。
採用深度優先搜索(DFS)遞歸遍歷目錄樹,將遇到的所有 File 對象收集到列表中,最後利用 Collections.sort() 按自然順序(路徑字典序)排序。關鍵步驟如下:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public final class FileListing {
/**
* 公開入口:獲取指定目錄下所有文件的排序列表
* @param aStartingDir 起始目錄(必須存在、可讀、為目錄)
* @return 排序後的 File 列表
* @throws FileNotFoundException 目錄無效時拋出
*/
public static List<File> getFileListing(File aStartingDir) throws FileNotFoundException {
validateDirectory(aStartingDir);
List<File> result = getFileListingNoSort(aStartingDir);
Collections.sort(result); // 按 File.compareTo() 排序(路徑字典序)
return result;
}
/** 遞歸遍歷核心邏輯(不排序) */
private static List<File> getFileListingNoSort(File aStartingDir) throws FileNotFoundException {
List<File> result = new ArrayList<>();
File[] filesAndDirs = aStartingDir.listFiles();
if (filesAndDirs == null) {
throw new FileNotFoundException("無法讀取目錄內容: " + aStartingDir);
}
List<File> filesDirs = Arrays.asList(filesAndDirs);
for (File file : filesDirs) {
result.add(file); // 先加入當前條目(無論文件或目錄)
if (!file.isFile()) { // 若為目錄,遞歸處理
List<File> deeperList = getFileListingNoSort(file);
result.addAll(deeperList);
}
}
return result;
}
/** 目錄有效性校驗 */
private static void validateDirectory(File aDirectory) throws FileNotFoundException {
if (aDirectory == null) {
throw new IllegalArgumentException("目錄不能為 null");
}
if (!aDirectory.exists()) {
throw new FileNotFoundException("目錄不存在: " + aDirectory);
}
if (!aDirectory.isDirectory()) {
throw new IllegalArgumentException("非目錄路徑: " + aDirectory);
}
if (!aDirectory.canRead()) {
throw new IllegalArgumentException("目錄不可讀: " + aDirectory);
}
}
/** 測試入口 */
public static void main(String... args) throws FileNotFoundException {
if (args.length == 0) {
System.err.println("請提供起始目錄路徑作為參數");
return;
}
File startingDirectory = new File(args[0]);
List<File> files = getFileListing(startingDirectory);
for (File file : files) {
System.out.println(file);
}
}
}
FileNotFoundException,調用者可捕獲處理。listFiles() 可能返回 null(如權限不足),顯式檢查並拋出異常。File.compareTo() 按路徑字符串字典序排序,符合大多數場景預期。若處理超大目錄樹,建議改用 Java NIO.2 的 Files.walkFileTree 以獲得更好的內存控制與中斷能力。本實現適合中小規模目錄、需快速集成的場景。