Duyệt cây thư mục, xóa chỉ file (isFile()), đệ quy vào thư mục con (isDirectory()).
Ví dụ: Xóa file đệ quy
import java.io.File;
import java.io.IOException;
public class DeleteFilesRecursive {
public static void deleteFiles(File dir) {
File[] files = dir.listFiles();
if (files == null) return; // không phải thư mục hoặc lỗi I/O
for (File file : files) {
if (file.isFile()) {
boolean deleted = file.delete();
if (!deleted) {
System.err.println("Không xóa được: " + file.getAbsolutePath());
}
} else if (file.isDirectory()) {
deleteFiles(file); // đệ quy
}
}
}
public static void main(String[] args) throws IOException {
File root = new File("D:/ExampleDirectory");
System.out.println("Bắt đầu xóa file trong: " + root.getAbsolutePath());
deleteFiles(root);
System.out.println("Hoàn tất xóa file.");
}
}
Cấu trúc thư mục mẫu
ExampleDirectory/
├── file1.txt
├── file2.jpg
├── SubDir1/
│ ├── sub1.txt
│ └── sub2.txt
└── SubDir2/
├── sub3.txt
└── sub4.txt
Kết quả
Bắt đầu xóa file trong: D:\ExampleDirectory
Hoàn tất xóa file.
Thư mục SubDir1, SubDir2 vẫn tồn tại, chỉ các file bên trong bị xóa.
Java 7+: Files.walkFileTree (hiện đại hơn)
import java.nio.file.*;
import java.io.IOException;
public class DeleteFilesNIO {
public static void main(String[] args) throws IOException {
Path root = Paths.get("D:/ExampleDirectory");
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
System.out.println("Đã xóa: " + file);
return FileVisitResult.CONTINUE;
}
});
}
}
So sánh
| Đặc điểm | File.listFiles() + đệ quy | Files.walkFileTree |
|---|---|---|
| API | Legacy (java.io) | Modern (java.nio) |
| Xử lý lỗi | Thủ công | Tích hợp visitor pattern |
| Symbolic links | Không theo dõi | Có option FOLLOW_LINKS |
| Hiệu năng thư mục lớn | OK | Tốt hơn (streaming) |
Khuyến nghị: Dùng NIO.2 cho code mới.