Java复制整个目录推荐用Files.walk()配合Files.copy(),递归遍历并创建对应目录结构,再复制文件,支持属性保留和异常控制。

Java 复制整个目录(包括子目录和所有文件)不能只靠 File 类简单遍历,需要递归处理或使用更现代的 API。推荐用 java.nio.file 包中的 Files.walk() + Files.copy(),简洁、安全、支持符号链接和异常控制。
用 Files.walk() 递归复制(推荐)
核心思路:遍历源目录所有路径,对每个文件/目录在目标位置创建对应结构,再复制内容。
- 源路径必须存在且是目录;目标路径不能预先存在(否则抛异常),或需先清空
- 用
Files.createDirectories()确保目标子目录存在 - 跳过源根目录本身(只处理其下的条目)
- 复制时保留属性(如最后修改时间)可加
StandardCopyOption.COPY_ATTRIBUTES
示例代码:
Path src = Paths.get("srcDir");
Path dst = Paths.get("dstDir");
// 目标目录不能已存在(或手动删除/清空)
if (Files.exists(dst)) {
throw new IllegalStateException("目标目录已存在:" + dst);
}
try (Stream<path> stream = Files.walk(src)) {
stream.forEach(sourcePath -> {
try {
Path targetPath = dst.resolve(src.relativize(sourcePath));
if (Files.isDirectory(sourcePath)) {
Files.createDirectories(targetPath);
} else {
Files.createDirectories(targetPath.getParent()); // 确保父目录存在
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
}
} catch (IOException e) {
throw new RuntimeException("复制失败: " + sourcePath, e);
}
});
} catch (IOException e) {
throw new RuntimeException("遍历源目录失败", e);
}</path>
用 Files.copy() 配合 SimpleFileVisitor(更可控)
适合需要精细控制的场景,比如跳过特定文件、记录日志、处理异常不中断等。
- 继承
SimpleFileVisitor,重写preVisitDirectory和visitFile - 在
preVisitDirectory中创建目标子目录(跳过源根) - 在
visitFile中执行实际文件复制 - 返回
FileVisitResult.CONTINUE继续遍历
关键片段:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
Files.walkFileTree(src, new SimpleFileVisitor<path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
Path targetDir = dst.resolve(src.relativize(dir));
Files.createDirectories(targetDir);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Path targetFile = dst.resolve(src.relativize(file));
Files.createDirectories(targetFile.getParent());
Files.copy(file, targetFile, StandardCopyOption.REPLACE_EXISTING);
return FileVisitResult.CONTINUE;
}
});</path>
注意事项和常见问题
避免踩坑的关键细节:
- 不要用 File.renameTo() 或老式字节流逐个复制:效率低、不支持大文件、无法自动建目录、易出错
- 目标路径权限不足或磁盘满时会抛 IOException,务必捕获并处理
-
符号链接默认被当作普通文件复制(内容),如需复制链接本身,加
LinkOption.NOFOLLOW_LINKS -
Windows 下长路径可能触发“路径太长”异常,可用
\?前缀(需 JDK 11+ 或启用 Win10 长路径支持)
第三方库替代方案(可选)
如果项目已引入 Apache Commons IO,可用一行搞定:
FileUtils.copyDirectory(new File("srcDir"), new File("dstDir"));
但注意:它内部仍是递归实现,且不支持 JDK 21 的新特性;纯 JDK 方案更轻量、可控性更强。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










