在Java中是否有一种方法可以递归地删除整个目录?

在正常情况下,可以删除空目录。 然而,当涉及到删除包含内容的整个目录时,就不再那么简单了。

如何在Java中删除包含内容的整个目录?


当前回答

也许这个问题的解决方案是使用erickson回答中的代码重新实现File类的delete方法:

public class MyFile extends File {

  ... <- copy constructor

  public boolean delete() {
    if (f.isDirectory()) {
      for (File c : f.listFiles()) {
        return new MyFile(c).delete();
      }
    } else {
        return f.delete();
    }
  }
}

其他回答

rm -rf的性能比FileUtils.deleteDirectory要好得多。

经过大量的基准测试后,我们发现使用rm -rf比使用FileUtils.deleteDirectory快几倍。

当然,如果您有一个小的或简单的目录,这并不重要,但在我们的例子中,我们有多个gb和深度嵌套的子目录,使用FileUtils.deleteDirectory需要10分钟以上,使用rm -rf只需1分钟。

下面是我们粗略的Java实现:

// Delete directory given and all subdirectories and files (i.e. recursively).
//
static public boolean deleteDirectory( File file ) throws IOException, InterruptedException {

    if ( file.exists() ) {

        String deleteCommand = "rm -rf " + file.getAbsolutePath();
        Runtime runtime = Runtime.getRuntime();

        Process process = runtime.exec( deleteCommand );
        process.waitFor();

        return true;
    }

    return false;

}

如果您正在处理大型或复杂的目录,值得一试。

Guava提供了一行代码:morefiles . deleterecursive()。

与许多共享的示例不同,它只考虑符号链接,并且不会(默认情况下)删除所提供路径之外的文件。

在Guava 9之前,Guava一直支持files . deleterecursive (File)。

来自番石榴10:

弃用。该方法存在符号链接检测差和竞态条件差的问题。只有使用操作系统命令(如rm -rf或del /s)才能适当地支持此功能。这个方法计划在Guava 11.0版本中从Guava中移除。

因此,在番石榴11中没有这种方法。

也许这个问题的解决方案是使用erickson回答中的代码重新实现File类的delete方法:

public class MyFile extends File {

  ... <- copy constructor

  public boolean delete() {
    if (f.isDirectory()) {
      for (File c : f.listFiles()) {
        return new MyFile(c).delete();
      }
    } else {
        return f.delete();
    }
  }
}

一个有堆栈且没有递归方法的解决方案:

File dir = new File("/path/to/dir");
File[] currList;
Stack<File> stack = new Stack<File>();
stack.push(dir);
while (! stack.isEmpty()) {
    if (stack.lastElement().isDirectory()) {
        currList = stack.lastElement().listFiles();
        if (currList.length > 0) {
            for (File curr: currList) {
                stack.push(curr);
            }
        } else {
            stack.pop().delete();
        }
    } else {
        stack.pop().delete();
    }
}