Java nio - 无法删除已清空的目录

5

我正在尝试遍历文件树并删除所有的文件/目录。以下是代码:

        Files.walkFileTree(metricPath, new SimpleFileVisitor<Path>() {

            @Override
            public FileVisitResult visitFile(Path file,
                                             BasicFileAttributes attrs) throws IOException {
                Files.delete(file);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir,
                                                      IOException exc) throws IOException {
                if (exc == null) {
                    Files.delete(dir);
                    return FileVisitResult.CONTINUE;
                } else {
                    throw exc;
                }
            }
        });
    }

这段代码在单元测试之间运行,每个测试都会生成一个形如folder1/folder2/file的单独文件。当我尝试遍历这个目录树时,当尝试删除folder1时,会抛出DirectoryNotEmptyException异常,尽管它显然是空的...


可能是Java递归删除文件的重复问题。 - jlordo
实际上,另一个问题是针对当你有一个文件时的情况。在这种情况下,代码是为路径执行操作,而且不一定可以将路径转换为文件,因此例如 Commons IO 的 FileUtils 将无法使用。 - Hakanai
4个回答

0
使用Apache Commons FileUtils.deleteDirectory()或FileUtils.deleteQuietly()。

0

根据您的代码,我看不出有什么问题,除非一个文件/文件夹处于只读模式。在删除之前,您可能需要先探索更改文件权限。

您还可以尝试将Files.delete()方法放在以下覆盖上

public FileVisitResult visitFileFailed(Path file, IOException exc)

参考: JAVA NIO目录删除


0

你检查了那个目录中的隐藏文件吗?在Windows上,可能有一些进程打开了这个目录并且文件句柄仍然存在于系统句柄表中。在这种情况下,目录被锁定,Java可能会抛出该异常。


基本上,在调用 folder1 的 postVisit 时,folder2 的 postVisit 仍然存在。看起来像是 Java 的错误... - Bober02
我怀疑这是Java中JRE源代码中存在已久的错误。它早就应该被解决了。你能再解释一遍你刚才说的“文件夹1的postVisit仍然存在bla bla bla”是什么意思吗?postVisit是什么? - Archer
postVisitDirectory 方法针对 folder1 失败,因为其中含有 folder2... 我不知道为什么先调用了 folder1 的 postVisit 方法而不是先调用 folder2 的。 - Bober02
根据这篇 javadoc,postVisitDirectory仅在所有条目被访问后才会被调用。然而:当目录的迭代过早完成(通过visitFile方法返回SKIP_SIBLINGS或在迭代目录时发生I/O错误)时,也会调用此方法。 - Archer

-2

3
确实,但并没有回答问题。 - user207421
已确认。然而,它提供了一个简单的解决方案,可能会让人们感到满意。 - matsev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接