备份目录触发DirectoryNotEmptyException,REPLACE_EXISTING未生效求助
问题解决:DirectoryNotEmptyException 处理方案
核心原因
StandardCopyOption.REPLACE_EXISTING 仅对文件生效,无法覆盖已存在且非空的目录。当Files.walk遍历到源目录本身时,若目标目录已存在且包含内容,执行Files.copy就会抛出DirectoryNotEmptyException。
修复代码
修改目录备份逻辑,先处理目标目录的存在性,同时优化资源管理:
try { if (srcFileOrDir.isFile()) { File destFile = new File(destDir.getAbsolutePath() + File.separator + srcFileOrDir.getName()); Files.copy(srcFileOrDir.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING); } else { // 处理目录 String[] pathParts = srcFileOrDir.getAbsolutePath().split("\\\\"); File targetRootDir = new File(destDir.getAbsolutePath() + File.separator + pathParts[pathParts.length - 1]); // 若目标根目录已存在,先递归删除(从最深层级开始,避免目录非空错误) if (targetRootDir.exists()) { Files.walk(targetRootDir.toPath()) .sorted(Comparator.reverseOrder()) .forEach(path -> { try { Files.delete(path); } catch (IOException e) { e.printStackTrace(); } }); } // 遍历源目录执行复制,用try-with-resources确保流资源关闭 try (Stream<Path> stream = Files.walk(srcFileOrDir.toPath())) { stream.forEach(source -> { Path destination = targetRootDir.toPath().resolve(srcFileOrDir.toPath().relativize(source)); try { if (Files.isDirectory(source)) { // 创建目标目录(自动创建父目录) Files.createDirectories(destination); } else { // 复制文件,替换已存在的文件 Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING); } } catch (IOException e) { e.printStackTrace(); } }); } JOptionPane.showMessageDialog(null, "Backup was created successfully at " + targetRootDir.getAbsolutePath(), "Success!", JOptionPane.INFORMATION_MESSAGE); } } catch (IOException e) { e.printStackTrace(); }
关键改动说明
- 递归清理目标目录:通过倒序遍历目标目录,先删除子文件/子目录再删除父目录,彻底清空已存在的备份目录。
- 分离目录与文件处理:明确区分路径类型,目录直接创建,文件使用
REPLACE_EXISTING覆盖,避免混淆操作逻辑。 - 资源安全管理:用
try-with-resources包裹Files.walk流,确保遍历完成后自动关闭资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Lucifer
相关产品推荐
相关产品推荐

