删除目录中的所有文件(但不是目录) - 一个班轮解决方案

时间:2012-11-02 13:04:50

标签: java file-io apache-commons-io

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

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

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

11 个答案:

答案 0 :(得分:300)

FileUtils.cleanDirectory(directory); 

同一文件中提供了此方法。这也将递归删除其下的所有子文件夹和文件。

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

答案 1 :(得分:242)

你的意思是?

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

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

答案 2 :(得分:58)

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()方法。

答案 3 :(得分:26)

Java 8 Stream

这只会删除 ABC 中的文件(子目录不受影响):

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

这仅删除 ABC (和子目录)中的文件:

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

^此版本需要处理IOException

答案 4 :(得分:11)

或者在Java 8中使用它:

try {
  Files.newDirectoryStream( directory ).forEach( file -> {
    try { Files.delete( file ); }
    catch ( IOException e ) { throw new UncheckedIOException(e); }
  } );
}
catch ( IOException e ) {
  e.printStackTrace();
}
很可惜,异常处理是如此笨重,否则它将是一个单行...

答案 5 :(得分:5)

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");
} }  }}

答案 6 :(得分:2)

删除目录中的所有文件说“C:\ Example”

<?php
    $fname = "$_POST[fname]";
    $lname = "$_POST[lname]";
//these value getting from another form
?>
<form action="test.php" method="post" class="form-inline vh_pre_reg_form">
<!-- Now I want to send them by this form-->
            <div class="form-group">
                <label>First Name</label>
                <span><?php echo $fname; ?></span>
            </div>
            <div class="form-group">
                <label>Last Name</label>
                <span><?php echo $lname; ?></span>
            </div>
<input name="submit" id="btnValidate" type="submit" value="Submit"/>
</form>

答案 7 :(得分:1)

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"))

声明它会起作用。

答案 8 :(得分:1)

另一个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);
    }
}

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

我尝试创建一个尽可能简洁的解决方案。

答案 9 :(得分:1)

rm -rf的性能要比FileUtils.cleanDirectory高。

这不是一种单线解决方案,但是经过广泛的基准测试,我们发现使用rm -rf的速度比使用FileUtils.cleanDirectory的速度快好几倍。

当然,如果您的目录很小或简单,那都没关系,但是在我们的例子中,我们有多个千兆字节和深层嵌套的子目录,其中FileUtils.cleanDirectory会花费10分钟以上,而只有1分钟与rm -rf

这是我们的粗略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;

}

如果要处理大型或复杂目录,则值得尝试。

答案 10 :(得分:0)

我认为这会起作用(基于先前的NonlinearFruit答案):

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

干杯!