贝利信息

在Java里开发文件拷贝小工具_Java文件IO基础实战说明

日期:2026-01-02 00:00 / 作者:P粉602998670
Files.copy() 是 Java 7+ 安全高效拷贝文件的首选,需指定 REPLACE_EXISTING 和 COPY_ATTRIBUTES 参数以避免异常并保留元数据;大文件应退化为带 8KB 缓冲的流式拷贝;目录复制须手动递归;Windows 中文路径需设置 -Dfile.encoding=UTF-8。

Files.copy() 最快实现安全拷贝

Java 7+ 推荐直接用 Files.copy(),它底层自动选择最优路径(比如支持 FileChannel.transferTo() 零拷贝),比手动读写流快且不易出错。关键是要传对参数,否则可能覆盖失败或丢元数据。

Path src = Paths.get("/tmp/data.txt");
Path dst = Paths.get("/backup/data.txt");
Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);

处理大文件时避免 OutOfMemoryError

Files.copy() 拷贝几个 GB 的文件一般没问题,但若在内

存受限环境(如嵌入式 JVM 或容器限 256MB)下频繁调用,仍可能触发 GC 压力。此时应退回到带缓冲的流式拷贝,并控制缓冲区大小。

try (InputStream in = new FileInputStream(src.toFile());
     OutputStream out = new FileOutputStream(dst.toFile())) {
    byte[] buf = new byte[8192];
    int len;
    while ((len = in.read(buf)) != -1) {
        out.write(buf, 0, len);
    }
}

复制目录必须自己递归,Files.copy() 不支持

Files.copy() 只处理单个文件,传入目录会直接抛 IOException:“Unsupported operation: isDirectory”。要复制整个目录树,得手动遍历 + 判断类型 + 创建子目录。

Path srcDir = Paths.get("/project/src");
Path dstDir = Paths.get("/backup/src");
Files.walk(srcDir)
     .forEach(srcPath -> {
         Path dstPath = dstDir.resolve(srcDir.relativize(srcPath));
         try {
             if (Files.isRegularFile(srcPath)) {
                 Files.createDirectories(dstPath.getParent());
                 Files.copy(srcPath, dstPath, StandardCopyOption.REPLACE_EXISTING);
             }
         } catch (IOException e) {
             throw new UncheckedIOException(e);
         }
     });

Windows 下中文路径乱码?检查默认字符集

在 Windows 上用 Paths.get("C:\\用户\\文档\\file.txt")InvalidPathException 或拷贝后文件名变问号,大概率是 JVM 启动时没指定文件编码。Java 默认用系统 locale 解析路径字符串,而 Windows 中文版默认是 GBK,但 JVM 8+ 在多数情况下按 UTF-8 解析。

真正容易被忽略的是:这个编码问题不会在开发机(UTF-8 环境)暴露,一到客户内网 Windows 机器就崩,而且错误日志里只报“path not found”,得盯住 Paths.get(...).toAbsolutePath() 的输出才能确认是否解析变形。