DirectoryNotEmptyException在复制文件时发生

huangapple go评论65阅读模式
英文:

DirectoryNotEmptyException while copying files

问题

我写了一个程序,可以将文件或目录备份到选定的文件夹。以下是我的代码片段:

try {
    if (srcFileOrDir.isFile()) {
        File destFile = new File(destDir.getAbsolutePath() + File.separator + srcFileOrDir.getName());
        Files.copy(srcFileOrDir.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
    }
    else { //isDirectory
        String[] pathParts = srcFileOrDir.getAbsolutePath().split("\\\\");
        destDir = new File(destDir.getAbsolutePath() + File.separator + pathParts[pathParts.length-1]);
        Files.walk(srcFileOrDir.toPath()).forEach(source -> {
            Path destination = destDir.toPath().resolve(srcFileOrDir.toPath().relativize(source));
            try {
                Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
    JOptionPane.showMessageDialog(null, "备份已成功创建在" + destDir.getAbsolutePath(), "成功!", JOptionPane.INFORMATION_MESSAGE);
}
catch (IOException e) {
    e.printStackTrace();
}

问题是,当我尝试执行Files.copy()时,程序会抛出DirecroryNotEmptyException异常。只有在尝试备份目录时才会引发异常。如果我备份文件,一切正常工作。

我使用了REPLACE_EXISTING选项,但我的程序忽略了它。提前感谢您的帮助。

英文:

I wrote a program, where you can backup file or directory to chosen folder. Here is piece of my code:

try {
    if (srcFileOrDir.isFile()) {
        File destFile = new File(destDir.getAbsolutePath() + File.separator + srcFileOrDir.getName());
        Files.copy(srcFileOrDir.toPath(), destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
    }
    else { //isDirectory
        String[] pathParts = srcFileOrDir.getAbsolutePath().split("\\\\");
        destDir = new File(destDir.getAbsolutePath() + File.separator + pathParts[pathParts.length-1]);
        Files.walk(srcFileOrDir.toPath()).forEach(source -> {
            Path destination = destDir.toPath().resolve(srcFileOrDir.toPath().relativize(source));
            try {
                Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
    JOptionPane.showMessageDialog(null, "Backup was created successfully at " +       destDir.getAbsolutePath(), "Success!", JOptionPane.INFORMATION_MESSAGE);
}
catch (IOException e) {
    e.printStackTrace();
}

The problem is that program throws DirecroryNotEmptyException when i am trying to execute Files.copy(). The exception is thrown only if i am trying to backup directory. If i am backuping file everything works normal.

I used REPLACE_EXISTING option, but my program ignores it. Thanks in advance.

答案1

得分: 0

您的代码将仅处理将目录复制到新位置。参见Files.copy的文档:

> 抛出DirectoryNotEmptyException - 指定了REPLACE_EXISTING选项,但由于它是非空目录,无法替换文件。

因此,复制现有目录是不必要的,只需在复制行前通过检查!isDirectory()来添加前缀。

if (!Files.isDirectory(destination)) {
    System.out.format("Files.copy(%s, %s)%n", source, destination);
    Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
}

测试srcFileOrDir.isFile()也是不必要的,因为Files.walk适用于文件或目录。将所有内容汇总,包括异常处理、无路径拆分和新的Path方法:

private static void copyToDirectory(Path src, Path destDir) throws IOException {
    final Path dest = destDir.resolve(src.getFileName());
    System.out.format("copying %s => %s%n", src, dest);
    Files.walk(src).forEach(source -> {
        Path destination = dest.resolve(src.relativize(source));
        try {
            if (!Files.isDirectory(destination)) {
                System.out.format("Files.copy(%s, %s)%n", source, destination);
                Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    });
}
英文:

Your code will only handle directory copying to a new location. See the documentation of Files.copy:

> throws DirectoryNotEmptyException - the REPLACE_EXISTING option is
> specified but the file cannot be replaced because it is a non-empty
> directory

Therefore it is unnecessary to copy a directory that exists, just prefix copy line by checking !isDirectory() beforehand.

if (!Files.isDirectory(destination)) {
    System.out.format("Files.copy(%s, %s)%n",source, destination);
    Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
}

It is also unnecessary to test for srcFileOrDir.isFile() as Files.walk works for file or directory. Put that all together with exception handling, no path splitting, and clean new Path only method:

private static void copyToDirectory(Path src, Path destDir) throws IOException {
    final Path dest = destDir.resolve(src.getFileName());
    System.out.format("copying %s => %s%n",src, dest);
    Files.walk(src).forEach(source -> {
        Path destination = dest.resolve(src.relativize(source));
        try {
            if (!Files.isDirectory(destination)) {
                System.out.format("Files.copy(%s, %s)%n",source, destination);
                Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    });
}

huangapple
  • 本文由 发表于 2023年5月13日 22:54:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76243347.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定