Java递归复制文件及目录时抛出FileAlreadyExistsException问题排查
解决递归复制目录时的FileAlreadyExistsException问题
问题原因
你的代码里,处理目录的逻辑执行完递归调用后,不管当前项是文件还是目录,都会执行最后的Files.copy语句。当处理目录时,你已经在目标路径创建了对应的目录,此时再调用Files.copy去复制这个目录(而非目录内的内容),就会触发FileAlreadyExistsException——因为目标目录已存在,且Files.copy默认不允许覆盖目录。
修正后的代码
import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; public class DirectoryCopier { public void copyFiles(File src, File dst) throws IOException { // 列出源目录下的所有项,处理无权限或目录不存在的情况 String[] files = src.list(); if (files == null) { return; } // 确保目标根目录存在 if (!dst.exists()) { dst.mkdirs(); } for (String fileName : files) { File srcItem = new File(src, fileName); File dstItem = new File(dst, fileName); if (srcItem.isDirectory()) { // 递归复制子目录内容 copyFiles(srcItem, dstItem); } else { // 仅复制文件,添加覆盖选项避免文件已存在的报错 Files.copy(srcItem.toPath(), dstItem.toPath(), StandardCopyOption.REPLACE_EXISTING); } } } }
关键修改点
- 路径拼接优化:不再用硬编码的
\\拼接路径,改用File构造方法new File(src, fileName)自动适配系统路径分隔符,避免跨平台问题。 - 区分文件与目录逻辑:只有当前项是文件时才执行
Files.copy,目录的复制通过递归完成,无需额外调用复制目录的操作。 - 添加文件覆盖选项:使用
StandardCopyOption.REPLACE_EXISTING,如果目标文件已存在会直接覆盖,避免文件层面的存在性异常。 - 空值安全处理:增加
src.list()返回null的判断,防止源目录无权限或不存在时触发空指针异常。 - 提前创建目标根目录:循环前先确保目标根目录存在,避免首次调用时的目录缺失问题。
内容的提问来源于stack exchange,提问作者Vince
相关产品推荐
相关产品推荐

