为什么在递归删除目录时遇到DirectoryNotEmptyException?

时间:2016-10-18 13:58:41

标签: java io java-7 nio

我有一些代码,应该使用java.nio包递归删除目录。代码基本上是从http://www.adam-bien.com/roller/abien/entry/java_7_deleting_recursively_a复制而来,如下所示:

public class NotEmptyDirDemo {
    public static void main(String[] pArgs) throws Exception {
        final Path path = Paths.get("d:/tmp/woda");
        Assert.assertTrue(Files.isDirectory(path));
        new NotEmptyDirDemo().removeDir(path);
        Assert.assertFalse(Files.isDirectory(path));
    }

    protected void removeDir(Path pDir) throws IOException {
        final FileVisitor<Path> fv = new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path pDir,
                             BasicFileAttributes pAttrs) throws IOException {
                return super.preVisitDirectory(pDir, pAttrs);
            }

            @Override
            public FileVisitResult postVisitDirectory(Path pDir, IOException pExc) throws IOException {
                final FileVisitResult res = super.postVisitDirectory(pDir, pExc);
                Files.delete(pDir);
                return res;
            }

            @Override
            public FileVisitResult visitFile(Path pFile, BasicFileAttributes pAttrs) throws IOException {
                if (!Files.isWritable(pFile)) {
                    pFile.toFile().setWritable(true);
                }
                Files.delete(pFile);
                return super.visitFile(pFile, pAttrs);
            }
        };
        Files.walkFileTree(pDir, fv);
    }
}

现在,我可以想象在执行这些事情时会发生所有不好的事情(例如,缺少删除权限等等。但是,这个让我感到惊讶:

Exception in thread "main" java.nio.file.DirectoryNotEmptyException:
     d:\tmp\woda\woda\work
at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:266)
at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
at java.nio.file.Files.delete(Files.java:1126)
at com.foo.demo.NotEmptyDirDemo$1.postVisitDirectory(NotEmptyDirDemo.java:32)
at com.foo.demo.NotEmptyDirDemo$1.postVisitDirectory(NotEmptyDirDemo.java:1)
at java.nio.file.Files.walkFileTree(Files.java:2688)
at java.nio.file.Files.walkFileTree(Files.java:2742)
at com.foo.demo.NotEmptyDirDemo.removeDir(NotEmptyDirDemo.java:45)
at com.foo.demo.NotEmptyDirDemo.main(NotEmptyDirDemo.java:18)

目录walker遍历目录树。如果找到一个目录,它会迭代它,最后删除它(在postVisitDirectory中)。如果找到一个文件,也会被删除(在visitFile中)。

因此,正在删除的目录应始终为空。但事实并非如此。

有任何合理的解释吗?

谢谢,

约亨

0 个答案:

没有答案