開發者嘗試將相冊照片移動至百度搜索預設圖片目錄,代碼邏輯為:打開輸入流讀取源文件,輸出流寫入目標文件,成功後刪除源文件。運行時無異常拋出,但目標目錄無文件,源文件卻不見了。
File newfile = new File(newPath); // newPath 是目錄路徑
if (!newfile.exists()) { return false; }
OutputStream opStream = new FileOutputStream(newfile); // 錯誤:對目錄創建輸出流
newFile 指向的是目標目錄而非目標文件,導致 `FileOutputStream` 拋出 `FileNotFoundException`(被 catch 吞噬),隨後 `oldfile.delete()` 執行,源文件被刪除,數據實際未寫入任何文件。
public static boolean moveFile(File src, File destDir) {
if (!src.exists() || !destDir.exists() || !destDir.isDirectory()) return false;
File dest = new File(destDir, src.getName());
// 1. 嘗試原子重命名
if (src.renameTo(dest)) return true;
// 2. 降級為流拷貝
try (FileChannel in = FileChannel.open(src.toPath(), StandardOpenOption.READ);
FileChannel out = FileChannel.open(dest.toPath(),
StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
long transferred = in.transferTo(0, in.size(), out);
if (transferred == src.length()) {
src.delete(); // 校驗大小後再刪
return true;
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
永遠不要在確認寫入成功前刪除源文件;捕獲異常時務必打印堆疊跟踪,不要 `return false` 吞噬錯誤信息;適配 Android 版本差異,善用 `Context.getExternalFilesDir()` 等受保護目錄避免權限糾紛。