使用java安全的移动文件

File.renameTo() 在 Windows 跨磁盘 / 跨分区移动一定会失败 (C 盘→D 盘)。 下面提供 JDK 原生 NIO 实现的可靠移动工具:逻辑:复制完整文件 → 校验大小 → 删除源文件,兼容同盘、跨分区、网络目录。 增加异常重试、自动关闭流,防止文件句柄泄漏。

复制代码
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Windows可靠跨分区移动文件
 * @param sourceFile 源文件
 * @param targetDirPath 目标文件夹路径(文件夹不存在自动创建)
 * @return true 移动成功,false失败
 */
private boolean moveFileSafe(File sourceFile, String targetDirPath) {
    if (!sourceFile.exists() || !sourceFile.isFile()) {
        System.err.println("源文件不存在:" + sourceFile.getAbsolutePath());
        return false;
    }
    Path sourcePath = sourceFile.toPath();
    File targetDir = new File(targetDirPath);
    // 目标目录不存在自动创建
    if (!targetDir.exists()) {
        targetDir.mkdirs();
    }
    // 构建目标完整路径
    Path targetPath = Paths.get(targetDir.getAbsolutePath(), sourceFile.getName());

    // 如果目标同名文件存在,可选策略:覆盖 / 重命名,这里选择【覆盖】
    try {
        // Files.move 底层优先尝试rename(同盘瞬间完成);跨盘会自动复制+删除
        Files.move(sourcePath, targetPath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
        return true;
    } catch (IOException e) {
        System.err.println("NIO move直接失败,降级为【复制文件+删除源文件】方案:" + sourceFile);
        try {
            // 降级方案:复制
            Files.copy(sourcePath, targetPath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
            // 校验文件大小一致
            long srcSize = sourceFile.length();
            long destSize = new File(targetPath.toString()).length();
            if (srcSize == destSize && srcSize > 0) {
                // 复制成功,删除源文件
                Files.delete(sourcePath);
                return true;
            } else {
                System.err.println("文件复制后大小不一致,放弃删除源文件");
                // 清理不完整目标文件
                Files.deleteIfExists(targetPath);
                return false;
            }
        } catch (IOException ex) {
            System.err.println("文件移动最终失败!");
            ex.printStackTrace();
            return false;
        }
    }
}
相关推荐
mqiqe1 小时前
AgentScope Java 2.0 Agent 状态存储(AgentStateStore)深度解析:构建可恢复、可扩展的智能体运行时
java·运维·网络
zhifou1234561 小时前
java 17升级安装
java·开发语言
用户3721574261351 小时前
如何使用 Java 将 Markdown 转换为 PDF(含自定义设置)
java
用户3721574261352 小时前
如何使用 Java 在 Word 文档中添加和删除水印:分步指南
java
王中阳Go3 小时前
老板用AI三天写到90%,让我明天上线:Java 团队怎么接这10%的烂摊子?
java
gugucoding4 小时前
55. 【Java】Maven:项目构建的“管家”
java·maven
郑州光合科技余经理4 小时前
海外版多语言团购系统架构:主数据互通与核销边界
java·开发语言·前端·后端·系统架构·php·ai编程
Jesse_EC5 小时前
为什么我设置的 contentLength 到了消费端变成了 0?
java
vipxieliang5 小时前
ValidX 的 Date 和 DateTime vs JPA 的 Temporal 对比
java·后端