删除目录中的所有文件(但不包括目录)-一个线性解决方案

我想删除ABC目录下的所有文件。

当我尝试使用FileUtils.deleteDirectory(new File("C:/test/ABC/"));时,它也会删除文件夹ABC。

是否有一个一行解决方案,我可以删除目录内的文件,但不是目录?

306673 次浏览

你是说像?

for(File file: dir.listFiles())
if (!file.isDirectory())
file.delete();

这将只删除文件,而不是目录。

import org.apache.commons.io.FileUtils;


FileUtils.cleanDirectory(directory);

在同一文件中有此方法可用。这也会递归地删除它们下面的所有子文件夹和文件。

文档:org.apache.commons.io.FileUtils.cleanDirectory

Peter Lawrey的回答很好,因为它很简单,不依赖于任何特殊的东西,这是你应该做的方式。如果你需要删除子目录和它们的内容,使用递归:

void purgeDirectory(File dir) {
for (File file: dir.listFiles()) {
if (file.isDirectory())
purgeDirectory(file);
file.delete();
}
}

为了节省子目录及其内容(你的问题的一部分),修改如下:

void purgeDirectoryButKeepSubDirectories(File dir) {
for (File file: dir.listFiles()) {
if (!file.isDirectory())
file.delete();
}
}

或者,既然你想要一个单行的解决方案:

for (File file: dir.listFiles())
if (!file.isDirectory())
file.delete();

使用外部库来完成如此琐碎的任务并不是一个好主意,除非您需要这个库来完成其他任务,在这种情况下,最好使用现有的代码。无论如何,你似乎在使用Apache库,所以使用它的FileUtils.cleanDirectory()方法。

package com;
import java.io.File;
public class Delete {
public static void main(String[] args) {


String files;
File file = new File("D:\\del\\yc\\gh");
File[] listOfFiles = file.listFiles();
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
files = listOfFiles[i].getName();
System.out.println(files);
if(!files.equalsIgnoreCase("Scan.pdf"))
{
boolean issuccess=new File(listOfFiles[i].toString()).delete();
System.err.println("Deletion Success "+issuccess);
}
}
}
}
}

如果你想删除所有文件删除

if(!files.equalsIgnoreCase("Scan.pdf"))

语句是可以的。

或者在Java 8中使用这个:

try {
Files.newDirectoryStream( directory ).forEach( file -> {
try { Files.delete( file ); }
catch ( IOException e ) { throw new UncheckedIOException(e); }
} );
}
catch ( IOException e ) {
e.printStackTrace();
}

很遗憾异常处理是如此庞大,否则它将是一行程序…

public class DeleteFile {
public static void main(String[] args) {
String path="D:\test";
File file = new File(path);
File[] files = file.listFiles();
for (File f:files)
{if (f.isFile() && f.exists)
{ f.delete();
system.out.println("successfully deleted");
}else{
system.out.println("cant delete a file due to open or error");
} }  }}

要删除目录中的所有文件,请输入“C:\Example”

File file = new File("C:\\Example");
String[] myFiles;
if (file.isDirectory()) {
myFiles = file.list();
for (int i = 0; i < myFiles.length; i++) {
File myFile = new File(file, myFiles[i]);
myFile.delete();
}
}

Java 8流

这只删除美国广播公司中的文件(子目录不受影响):

Arrays.stream(new File("C:/test/ABC/").listFiles()).forEach(File::delete);

这只删除美国广播公司(和子目录)中的文件:

Files.walk(Paths.get("C:/test/ABC/"))
.filter(Files::isRegularFile)
.map(Path::toFile)
.forEach(File::delete);

^这个版本需要处理IOException

另一个Java 8 Stream解决方案删除文件夹的所有内容,包括子目录,但不删除文件夹本身。

用法:

Path folder = Paths.get("/tmp/folder");
CleanFolder.clean(folder);

代码是:

public interface CleanFolder {
static void clean(Path folder) throws IOException {


Function<Path, Stream<Path>> walk = p -> {
try { return Files.walk(p);
} catch (IOException e) {
return Stream.empty();
}};


Consumer<Path> delete = p -> {
try {
Files.delete(p);
} catch (IOException e) {
}
};


Files.list(folder)
.flatMap(walk)
.sorted(Comparator.reverseOrder())
.forEach(delete);
}
}

每个流解决方案都涉及文件的问题。walk或Files.delete这些方法会抛出IOException,这在流中处理起来很麻烦。

我试图创造一个更简洁的解决方案。

我认为这是可行的(基于非线性水果之前的答案):

Files.walk(Paths.get("C:/test/ABC/"))
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.filter(item -> !item.getPath().equals("C:/test/ABC/"))
.forEach(File::delete);

干杯!

rm -rf的性能更好。

这不是一个简单的解决方案,但经过大量的基准测试后,我们发现使用rm -rf比使用FileUtils.cleanDirectory快几倍。

当然,如果你有一个小或简单的目录,这并不重要,但在我们的例子中,我们有多个gb和深嵌套的子目录,其中FileUtils.cleanDirectory需要超过10分钟,而rm -rf只需要1分钟。

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

// Delete directory given and all subdirectories and files (i.e. recursively).
//
static public boolean clearDirectory( 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();


file.mkdirs(); // Since we only want to clear the directory and not delete it, we need to re-create the directory.


return true;
}


return false;


}

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