核心 API 差異
| 方法 | 行為 | 適用場景 |
mkdir() | 僅創建最後一級目錄,父目錄必須存在 | 確定父目錄已存在時 |
mkdirs() | 遞歸創建所有不存在的父目錄 | 通用推薦,無需判斷父目錄 |
delete() | 僅刪除空目錄或文件 | 空目錄/文件 |
| 遞歸刪除 | 先刪除子文件/子目錄,再刪除自身 | 非空目錄 |
完整工具類
public class FileUtils {
// 創建目錄(含父目錄)
public static boolean createDir(File dir) {
if (dir.exists()) return dir.isDirectory();
return dir.mkdirs(); // 自動遞歸創建父目錄
}
// 遞歸刪除文件/目錄
public static boolean deleteRecursive(File file) {
if (!file.exists()) return true;
if (file.isDirectory()) {
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
if (!deleteRecursive(child)) return false;
}
}
}
return file.delete();
}
// 刪除文件夾內容但保留文件夾
public static boolean clearDir(File dir) {
if (!dir.exists() || !dir.isDirectory()) return false;
File[] children = dir.listFiles();
if (children != null) {
for (File child : children) {
if (!deleteRecursive(child)) return false;
}
}
return true;
}
}
權限配置(Android 6.0+ 必須)
// 運行時申請 (Activity/Fragment)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQ_CODE);
}
Android 10+ (API 29) 分區存儲適配
- 優先使用
Context.getExternalFilesDir() / getCacheDir() —— 無需權限、應用卸載自動清理。
- 需訪問公共目錄(圖片/下載)請用 MediaStore API 插入/查詢,配合
MediaStore.createWriteRequest 申請用戶授權。
Environment.getExternalStorageDirectory() 已棄用,讀取返回的路徑在 Android 10+ 無寫入權限。
常見坑
listFiles() 返回 null 表示無權限或非目錄,必須判空。
- 遞歸刪除深層目錄棧溢出風險,極深目錄改用显式棧/隊列迭代。
- 文件被其他進程佔用(如圖庫掃描)導致刪除失敗,捕獲異常重試或延遲刪除。