本地 Windows 開發環境 File.renameTo() 正常修改文件夾名稱,部署至 Linux Tomcat 後失效,無異常拋出,返回 false。
rename(2) 系統調用支持目錄重命名public void renameFolder(String oldPath, String newPath) {
File oldFile = new File(oldPath);
File newFile = new File(newPath);
// 前置檢查
if (!oldFile.exists()) {
log.error("源目錄不存在: {}", oldPath);
return;
}
if (newFile.exists()) {
log.error("目標目錄已存在: {}", newPath);
return;
}
boolean result = oldFile.renameTo(newFile);
if (result) {
log.info("重命名成功: {} -> {}", oldPath, newPath);
} else {
log.error("重命名失敗: {} -> {} (檢查權限/佔用/跨設備)", oldPath, newPath);
}
}
| 原因 | 排查命令 | 解決 |
|---|---|---|
| 進程佔用目錄 | lsof +D /path/to/dir | 停止佔用進程或 fuser -k |
| 權限不足 | ls -ld /path/to/dir | chown tomcat:tomcat 或調整 ACL |
| 跨文件系統 | df -h /src /dest | 改用複製+刪除,或調整掛載點 |
| 不可變屬性 | lsattr /path/to/dir | chattr -i 移除 |
| SELinux 阻擋 | ausearch -m avc -ts recent | 調整策略或 setenforce 0 測試 |
ln -sfn)實現原子發布/回滾java.nio.file.Files.move()(JDK 7+),支持 REPLACE_EXISTING、ATOMIC_MOVE 選項,異常信息更豐富Path source = Paths.get(oldPath);
Path target = Paths.get(newPath);
try {
Files.move(source, target,
StandardCopyOption.ATOMIC_MOVE, // 同文件系統原子移動
StandardCopyOption.REPLACE_EXISTING);
log.info("NIO 移動成功");
} catch (AtomicMoveNotSupportedException e) {
// 跨文件系統回退
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
log.error("移動失敗", e);
}