在 Java 開發中,遍歷目錄結構與遞歸刪除資料夾是常見的檔案操作需求。本文提供兩個完整、可直接執行的實作範例,涵遞歸讀取、遞歸刪除,並說明關鍵 API 與注意事項。
File.list():回傳字串陣列(檔名),不含路徑。File.listFiles():回傳 File 物件陣列,含完整路徑,**推薦使用**。File.delete():僅能刪除「檔案」或「空目錄」。非空目錄必須先遞歸刪除內容物。File.isDirectory() / isFile():判斷類型。list() + 字串拼接路徑)package test.com;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ReadFile {
/**
* 遞歸讀取指定路徑下的所有檔案名稱
* @param filepath 目錄路徑
* @return true 表示完成
*/
public static boolean readfile(String filepath) throws FileNotFoundException, IOException {
File file = new File(filepath);
if (!file.exists()) {
throw new FileNotFoundException("路徑不存在: " + filepath);
}
if (file.isFile()) {
System.out.println("檔案: " + file.getName());
} else if (file.isDirectory()) {
String[] filelist = file.list();
if (filelist == null) return true; // 空目錄或無權限
for (String name : filelist) {
// 注意:此處需手動處理路徑分隔符,建議用 File 建構子
File child = new File(filepath + File.separator + name);
if (child.isFile()) {
System.out.println("檔案: " + child.getName());
} else if (child.isDirectory()) {
readfile(child.getAbsolutePath()); // 遞歸
}
}
}
return true;
}
/**
* 遞歸刪除目錄及其所有內容
* @param delpath 待刪除路徑
* @return true 表示成功
*/
public static boolean deletefile(String delpath) throws IOException {
File file = new File(delpath);
if (!file.exists()) return true; // 不存在視為成功
if (file.isFile()) {
return file.delete();
} else if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
deletefile(child.getAbsolutePath()); // 遞歸刪除子項
}
}
// 此時目錄應為空,可刪除自身
return file.delete();
}
return false;
}
public static void main(String[] args) {
try {
// 測試讀取
readfile("C:/Users/SW/Desktop/TestFolder");
// 測試刪除(謹慎使用!)
// deletefile("D:/Temp/TestDelete");
System.out.println("操作完成");
} catch (IOException e) {
e.printStackTrace();
}
}
}
listFiles()、專案相對路徑、詳細資訊輸出)package otherstudy;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestReadFile {
/**
* 取得專案 WebRoot 絕對路徑(適用於部署在 Servlet 容器的專案)
*/
String getProjectPath() {
String path = this.getClass().getResource("/").getPath(); // /d:/workspace/project/WebRoot/WEB-INF/classes/
return path.substring(1, path.indexOf("WEB-INF/classes"));
}
/**
* 遞歸讀取並印出詳細資訊
*/
public static boolean readAllFile(String filepath) throws FileNotFoundException, IOException {
File file = new File(filepath);
if (!file.exists()) throw new FileNotFoundException("路徑不存在: " + filepath);
if (file.isFile()) {
printFileInfo(file, "檔案資訊");
} else if (file.isDirectory()) {
System.out.println("\n資料夾內容列表: " + file.getAbsolutePath());
File[] fileList = file.listFiles();
if (fileList != null) {
for (File child : fileList) {
if (child.isFile()) {
printFileInfo(child, " 檔案");
} else if (child.isDirectory()) {
readAllFile(child.getAbsolutePath()); // 遞歸
}
}
}
}
return true;
}
private static void printFileInfo(File f, String prefix) {
System.out.println(prefix + ": " + f.getName());
System.out.println(" 相對路徑: " + f.getPath());
System.out.println(" 絕對路徑: " + f.getAbsolutePath());
}
/**
* 遞歸刪除並印出刪除日誌
*/
public static boolean deleteFile(String delpath) throws FileNotFoundException, IOException {
File file = new File(delpath);
if (!file.exists()) return true;
if (file.isFile()) {
System.out.println("刪除檔案: " + file.getAbsolutePath());
return file.delete();
} else if (file.isDirectory()) {
File[] fileList = file.listFiles();
if (fileList != null) {
for (File child : fileList) {
deleteFile(child.getAbsolutePath());
}
}
System.out.println("刪除目錄: " + file.getAbsolutePath());
return file.delete();
}
return false;
}
public static void main(String[] args) {
TestReadFile trf = new TestReadFile();
String xmlPath = trf.getProjectPath() + "testDocs";
try {
readAllFile(xmlPath);
// deleteFile(xmlPath); // 謹慎啟用
} catch (Exception e) {
e.printStackTrace();
}
}
}
listFiles():回傳 File 陣列,自動處理路徑分隔符,跨平台相容性更好。null 回傳:list() 與 listFiles() 在目錄不存在、無讀取權限、或非目錄時會回傳 null,必須判斷避免 NullPointerException。File.separator:而非硬編碼 "/" 或 "\\",確保 Windows/Linux/macOS 相容。IOException,建議在呼叫端統一捕獲並記錄日誌,避免中斷主流程。Files.walkFileTree() (NIO.2) 實現更高效、更安全的目錄遍歷與刪除,支援訪問選項與屬性讀取。import java.nio.file.*;
import java.io.IOException;
public class ModernDelete {
public static void deleteDirectory(Path path) throws IOException {
Files.walkFileTree(path, new SimpleFileVisitor() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file); // 刪除檔案
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
if (exc != null) throw exc;
Files.delete(dir); // 刪除空目錄
return FileVisitResult.CONTINUE;
}
});
}
}
掌握遞歸目錄操作是 Java 檔案處理的基本功。建議在新專案中優先採用 NIO.2 API,舊專案維護時參考本文範例進行安全重構。