使用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;
        }
    }
}
相关推荐
你的保护色6 分钟前
多AS互联BGP4综合实验设计
java
某不知名網友26 分钟前
ROS2进阶:服务通信、自定义SRV接口、参数服务器与基于服务的参数通信详解
java·开发语言·microsoft
Wang's Blog36 分钟前
Java 项目实战: 交友项目 - MongoDB 入门:体系结构和命令行操作
java·mongodb·交友
小溪学编程36 分钟前
将 Bean 放入 Spring 容器中的方式有哪些?
java·后端·spring
java_nnnn40 分钟前
LeetCode刷题滑动窗口(水果成篮+找到字符串中所有字母的异位词)Java
java·开发语言·leetcode
用户37215742613543 分钟前
Java 读取、修改和清空 PDF 文档属性(元数据)
java
SL_staff1 小时前
从‘改一行代码等三天’到‘改完即生效’:实施工程师的逻辑引擎避坑手记
java·产品·全栈
小羊没烦恼!1 小时前
异步编程:线程概述及使用
java·开发语言·mysql·算法·c#
hhwyqwqhhwy1 小时前
设备树之 provider 和 consumer
java·linux·前端
\光辉岁月/1 小时前
9.日期时间类
java·date·localdatetime·日期类