使用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;
        }
    }
}
相关推荐
这个昵称不容易13 小时前
考试报名系统的设计与实现(SpringBoot + MySQL + Vue 三角色平台)
java·springboot·毕设
Adellle13 小时前
设计模式指南 (Java 版) ㊁
java·开发语言·设计模式
特立独行的猫A13 小时前
cj-tauri:用仓颉写桌面与鸿蒙 PC 应用
java·后端·python
Lonely丶墨轩14 小时前
从一个 404 到负数 ID:第三方接口开发中的几次排错
java
聪明的笨猪猪14 小时前
实际工程问题:AI生成MyBatis批量操作的SQL超限与性能雪崩
java·经验分享·面试·ai编程
文丑颜不良啊14 小时前
LeetCode2501~2520题目解析
java·leetcode
瑞雪兆丰年兮14 小时前
JavaWeb-day07-MySQL(DQL&多表设计)
java·开发语言·数据库·sql·mysql·javaweb·web
唐老板14 小时前
Spring Boot 4 默认开虚拟线程,HikariCP 却成瓶颈
java
2601_962106641 天前
【Java Set综合实战】商品管理系统 + 图书收藏系统|Product、Book自定义类全套代码
java
RuoyiOffice1 天前
SpringBoot+Vue3 凭证生命周期设计:审核、过账、冲销与反过账怎样保持账目一致
java·spring boot·事务·springboot3·财务系统·会计凭证·ruoyi office