255

I want to delete all files inside ABC directory.

When I tried with FileUtils.deleteDirectory(new File("C:/test/ABC/")); it also deletes folder ABC.

Is there a one liner solution where I can delete files inside directory but not directory?

Fahim Parkar
  • 30,974
  • 45
  • 160
  • 276
  • 2
    Thats because .deleteDirectory (even the name implies it) is used for deleting directory's. It will get the directory it is in if the file isn't a directory. – user1534664 Nov 02 '12 at 13:07
  • Try looking for other functions inside the FileUtils class, that delete files instead of directory's. – user1534664 Nov 02 '12 at 13:07
  • 1
    http://www.javacodeexamples.com/java-delete-file-example/ – user1534664 Nov 02 '12 at 13:08
  • 1
    Why do you specifically need a one-liner? Performance can't be the criteria, because any 3rd party library method, will do that recursively only. So it would give you the same performance? – Rohit Jain Nov 02 '12 at 13:09
  • 1
    One thing you can do is delete the directory and then re-create it. We found that using `rm -rf directory; mkdir directory` was faster than using `FileUtils.cleanDirectory`. – Joshua Pinter Oct 16 '19 at 18:51

11 Answers11

438
import org.apache.commons.io.FileUtils;

FileUtils.cleanDirectory(directory); 

There is this method available in the same file. This will also recursively deletes all sub-folders and files under them.

Docs: org.apache.commons.io.FileUtils.cleanDirectory

K.H.
  • 1,383
  • 13
  • 33
Reddy
  • 8,737
  • 11
  • 55
  • 73
  • 56
    Nice one, also to prevent people from having to look this up; here's the import: import org.apache.commons.io.FileUtils; – Paul Gregoire Jul 03 '13 at 16:00
  • 5
    I still do have to look up why the import cannot be found. It's because one must [download it from apache.org](http://commons.apache.org/proper/commons-io/download_io.cgi). – Tomáš Zato Jun 04 '14 at 16:05
  • pretty solution. Check this lib by gradle: compile "commons-io:commons-io:+" – Leo Nguyen Sep 26 '14 at 04:54
  • 1
    [Gradle dependency](http://mvnrepository.com/artifact/commons-io/commons-io) - compile group: 'commons-io', name: 'commons-io', version: '2.5'. – Jaydev May 25 '16 at 14:28
  • 1
    Note, we found calling `rm -rf directory` was much more efficient than using `FileUtils.cleanDirectory`. – Joshua Pinter Oct 16 '19 at 18:50
  • @Jaydev I thought we're supposed to use `implementation` instead of `compile`? – AndreKR Nov 06 '22 at 17:11
  • Don't forget to add in `build.gradle`: `dependencies { implementation 'commons-io:commons-io:2.11.0'}` – Kamil Jul 30 '23 at 06:49
308

Do you mean like?

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

This will only delete files, not directories.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 78
    This is definitley the better answer, since it does not use an external lib! – AlexWien Jan 17 '13 at 20:20
  • @AlexWien But OP is already using that library. You must have noticed that BTW. – amar Sep 04 '13 at 06:05
  • 12
    @amar but even then: when there is a standard method there is absolutley no reason to use an external one which does the same thing. One day he might want to get rid of the lib, or the lib is not supported anymore, or is not allowed to use the lib for license reasons, etc. (This all might not be an issue for this specific lib, but applies to many other ones) – AlexWien Sep 10 '13 at 13:58
  • 12
    This will fail to delete everything if you have subdirectories inside the root "dir" directory. – Bitcoin Cash - ADA enthusiast Sep 12 '13 at 07:04
  • 2
    @TiagoT True, this will not delete sub-directories which are not empty. – Peter Lawrey Sep 12 '13 at 07:05
  • 2
    @AlexWien - Not necessarily, as many nontrivial projects will _already_ be directly or indirectly (as a transitive dependency) referencing `commons-io`. No reason not to use the library if it's already there anyways. However, certainly a better answer in contexts where `commons-io` is unavailable for whatever reason. Such as [on Android](http://stackoverflow.com/questions/17359163/apache-commons-io-on-android). – aroth Jul 12 '16 at 07:16
  • 5
    `for(File file: dir.listFiles())` is probably meant as.... `for (File file : new java.io.File("C:\\DeleteMeFolder").listFiles())` ... – Hartmut Pfarr Oct 28 '16 at 17:39
  • @Peter: How can I delete all files till yesterday in a directory (but not directory) - one liner solution? – venkat Jun 30 '17 at 15:18
  • @venkat you can delete all files with a modification date of more than 24 hours. – Peter Lawrey Jul 01 '17 at 09:40
  • 2
    This should be the accepted answer. It is far more elegant. No external dependency and does exactly what OP asked for. – Stimpson Cat Feb 12 '18 at 14:12
  • This won't work for directories with huge number of files since `listFiles()` fails by memory. – antorqs Mar 21 '18 at 11:09
  • Since in some cases listFiles() may return null (dir does not exist, for example), it is better to add a check to avoid NPE crashes. – Anatoly Vdovichev Apr 02 '18 at 10:12
72

Peter Lawrey's answer is great because it is simple and not depending on anything special, and it's the way you should do it. If you need something that removes subdirectories and their contents as well, use recursion:

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

To spare subdirectories and their contents (part of your question), modify as follows:

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

Or, since you wanted a one-line solution:

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

Using an external library for such a trivial task is not a good idea unless you need this library for something else anyway, in which case it is preferrable to use existing code. You appear to be using the Apache library anyway so use its FileUtils.cleanDirectory() method.

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Chrissi
  • 1,188
  • 10
  • 9
  • 1
    On the other hand, if nobody is the first to use the external library, then it's less likely that others will expect to find similar behavior in that external library, and less likely that they will look there... don't we have enough Not Invented Here out there? If the library is cohesive and easy to add to my project, then I almost always prefer to add the library. – J. B. Rainsberger Aug 13 '16 at 19:52
48

Java 8 Stream

This deletes only files from ABC (sub-directories are untouched):

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

This deletes only files from ABC (and sub-directories):

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

^ This version requires handling the IOException

NonlinearFruit
  • 2,509
  • 1
  • 25
  • 27
14

Or to use this in Java 8:

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

It's a pity the exception handling is so bulky, otherwise it would be a one-liner ...

Christian Ullenboom
  • 1,388
  • 3
  • 24
  • 20
7

rm -rf was much more performant than FileUtils.cleanDirectory.

Not a one-liner solution but after extensive benchmarking, we found that using rm -rf was multiple times faster than using FileUtils.cleanDirectory.

Of course, if you have a small or simple directory, it won't matter but in our case we had multiple gigabytes and deeply nested sub directories where it would take over 10 minutes with FileUtils.cleanDirectory and only 1 minute with rm -rf.

Here's our rough Java implementation to do that:

// 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;

}

Worth trying if you're dealing with large or complex directories.

Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
6
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");
} }  }}
  • Great... This is the code sample that i was looking for despite minor syntax errors. Just needed to replace .exists with .exists() and replace system.out with System. out. – Supercoder Sep 16 '21 at 17:08
3

For deleting all files from directory say "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();
    }
}
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Mahesh Narwade
  • 609
  • 6
  • 7
2

Another Java 8 Stream solution to delete all the content of a folder, sub directories included, but not the folder itself.

Usage:

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

and the code:

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

The problem with every stream solution involving Files.walk or Files.delete is that these methods throws IOException which are a pain to handle in streams.

I tried to create a solution which is more concise as possible.

Community
  • 1
  • 1
hijack
  • 311
  • 2
  • 6
  • Rather then returning a null in the walk Function it would be better to return an empty stream (Stream.empty()). It's cleaner and the function always returns a stream. Null should be avoided when possible. – kaba713 Feb 07 '18 at 15:45
  • Thanks, I improved the answer with your suggestion – hijack Feb 08 '18 at 17:28
2

I think this will work (based on NonlinearFruit previous answer):

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

Cheers!

dansouza
  • 111
  • 5
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 you want to delete all files remove

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

statement it will work.

The Guy with The Hat
  • 10,836
  • 8
  • 57
  • 75
Mahesh
  • 75
  • 1
  • 6