使用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;
        }
    }
}
相关推荐
边境悍匪4 分钟前
蜗牛学苑 Java 智能体学习 Day39|SpringAI 会话存储、Function‑Call 工具调用、MCP 思维导图复盘
java·开发语言·spring boot·学习·阿里云
letisgo531 分钟前
JAVA 高级进阶02篇《并发编程三板斧:JMM、CAS与AQS的源码级拆解》
java·面试·并发编程·aqs·jmm
胡写代码35 分钟前
若依 + MyBatis-Plus,分页为什么悄悄失效了?
java·后端
yxlalm1 小时前
4.java秒杀项目第四课-后端商品后台接口
java·开发语言
宁之明起(B服)1 小时前
vulhub靶场(tomcat三件套:PUT写马、Ghostcat与manager弱口令)
java·tomcat
君顾11 小时前
家政派单小程序源码开发实战:从零搭建到上线全流程指南
java·开发语言·家政派单
流烟默1 小时前
HTTP 连接管理技术梳理:JDK KeepAliveCache 机制与池化选型
java·网络协议·http
阿酷tony1 小时前
视频专栏列表的防录屏水印和跑马灯效果(也可网站调用)
java·前端·音视频
洋不写bug2 小时前
排序(一)基础排序,插入|希尔|冒泡|直接选择排序详解
java·算法·排序算法·插入排序·冒泡排序·希尔排序·直接选择排序
xcl09252 小时前
全民健身智慧管理系统实战指南:从架构设计到部署落地
java·spring boot