使用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;
        }
    }
}
相关推荐
弹简特36 分钟前
【Java项目-企悦抽】15-活动管理模块02-活动创建测试与活动列表实现
java·开发语言·springboot
斯内普吖37 分钟前
(开源)水果蔬菜商城实战指南 基于 Java + SSM + Vue + MySQL
java·vue.js·mysql·开源
wang_shu_mo_ran44 分钟前
Spring IoC和DI概念篇
java·后端·spring
小狼154541 小时前
拼多多订单数据导出 CSV 实战:接口分页、字段平铺与 5 个数据坑,多多开票助手
java·前端·javascript
Joe_Wang51 小时前
【从0到1学习JVM · 25】同样都要停顿所有线程,Parallel比Serial到底强在哪
java·jvm·学习·垃圾回收
wuminyu1 小时前
JVM虚拟线程的底层实现原理分析
java·linux·c语言·jvm·c++
弹简特2 小时前
【Java项目-企悦抽】13-奖品管理模块-奖品列表和创建奖品的实现
java·开发语言·网络·springboot
小蒜学长2 小时前
基于Spring Boot+Vue的“禾源”农产品销售系统设计与实现(代码+数据库+LW)
java·spring boot·后端·农产品销售系统·产品溯源
光年20002 小时前
Mock-Server开箱即用的Mock服务
java·maven·mock·jetty
弹简特2 小时前
【Java项目-企悦抽】14-活动管理模块01-创建活动的实现
java·开发语言·springboot