在Java中是否有一种方法可以递归地删除整个目录?
在正常情况下,可以删除空目录。 然而,当涉及到删除包含内容的整个目录时,就不再那么简单了。
如何在Java中删除包含内容的整个目录?
在Java中是否有一种方法可以递归地删除整个目录?
在正常情况下,可以删除空目录。 然而,当涉及到删除包含内容的整个目录时,就不再那么简单了。
如何在Java中删除包含内容的整个目录?
当前回答
一行程序解决方案(Java8),递归删除所有文件和目录,包括起始目录:
try (var dirStream = Files.walk(Paths.get("c:/dir_to_delete/"))) {
dirStream
.map(Path::toFile)
.sorted(Comparator.reverseOrder())
.forEach(File::delete);
}
我们使用一个颠倒顺序的比较器,否则File::delete将不能删除可能非空的目录。所以,如果你想保留目录,只删除文件,只需在sorted()中删除比较器或完全删除排序,并添加文件过滤器:
try (var dirStream = Files.walk(Paths.get("c:/dir_to_delete/"))) {
dirStream
.filter(Files::isRegularFile)
.map(Path::toFile)
.forEach(File::delete);
}
其他回答
在Java 7中,我们终于可以通过可靠的符号链接检测来做到这一点。(我不认为Apache的commons-io现在有可靠的符号链接检测,因为它不处理Windows上用mklink创建的链接。)
出于历史原因,这里有一个java 7之前的答案,它遵循符号链接。
void delete(File f) throws IOException {
if (f.isDirectory()) {
for (File c : f.listFiles())
delete(c);
}
if (!f.delete())
throw new FileNotFoundException("Failed to delete file: " + f);
}
如果你有Spring,你可以使用filesystemutils . deleterecursive:
import org.springframework.util.FileSystemUtils;
boolean success = FileSystemUtils.deleteRecursively(new File("directory"));
虽然可以使用file.delete()轻松删除文件,但要删除的目录必须为空。使用递归可以很容易地做到这一点。例如:
public static void clearFolders(String[] args) {
for(String st : args){
File folder = new File(st);
if (folder.isDirectory()) {
File[] files = folder.listFiles();
if(files!=null) {
for(File f: files) {
if (f.isDirectory()){
clearFolders(new String[]{f.getAbsolutePath()});
f.delete();
} else {
f.delete();
}
}
}
}
}
}
下面的代码递归删除给定文件夹中的所有内容。
boolean deleteDirectory(File directoryToBeDeleted) {
File[] allContents = directoryToBeDeleted.listFiles();
if (allContents != null) {
for (File file : allContents) {
deleteDirectory(file);
}
}
return directoryToBeDeleted.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;
}
如果您正在处理大型或复杂的目录,值得一试。