我有一些代码,应该使用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中)。
因此,正在删除的目录应始终为空。但事实并非如此。
有任何合理的解释吗?
谢谢,
约亨