Tuesday, September 19, 2023

How to delete a directory with files in Java - Example

Deleting an empty directory is easy in Java, just use the delete() method of java.io.File class, but deleting a directory with files is unfortunately not easy. You just can't delete a folder if it contains files or sub folders. Calling delete() method on a File instance representing a non-empty directory will just return false without removing the directory. In order to delete this folder, you need to delete all files and subdirectories inside this folder. This may seem cumbersome, but unfortunately, there is no method that can delete a directory with files in Java, not even on Java 7 Files and Paths class.

So there are two choices, either you write your own method to recursively delete all files and folder before deleting a directory, or alternatively, you can use an open-source utility library like Apache Commons IO which will do this for you.

BTW, If you have to do this without using any third party library then you can use the example shown in this tutorial. You know what, I have asked this question couple of times to Java developers and only 3 out of 10 knows that you cannot delete a directory with files in Java.

I am not surprised because this is the kind of detail which is not obvious. Until you do it, you don't know this. Java isn't able to delete folders with data in it. You have to delete all files before deleting the folder, as shown in the first example of this tutorial.

And,  Java 7 got much better with files and directory support but there also, unfortunately, no direct method to delete a directory with files. Though, In JDK 7 you could use Files.walkFileTree() and Files.deleteIfExists() to delete a tree of files.




Java Program to delete non empty directory - Example Tutorial

Primary method to delete a file or directory in Java was File.delete() method form java.io package. This method can be used to delete a file or a nonempty directory but fail silently when it comes to deleting folder with files. 

If you ignore return value of this method, which is false if it failed to delete directory then you will never know that whether your program failed to remove some directory and I have seen many developers hit by this bullet. 

Thankfully, JDK 7 added another delete() method in Files utility class to delete file and directory, which throws IOException when a file cannot be deleted. This is really useful for troubleshooting purpose e.g. to find out why a file cannot be deleted. 

There is one more similar method, Files.deleteIfExists(), which is slightly more readable than original delete() method from File class. 

Now coming back to our original question, how to delete a folder with files or sub folder inside it. Well, we need to write a program which can recursively check all files and folder and delete them before deleting the top level directory


How to delete non empty directories in Java


In this example, I have create a directory structure with one directory containing a file and a sub-directory containing another file and tried to delete the top directory using our method. 

In this program, I have two overloaded method, deleteDirectory(File file) and deleteDirectory(String path) to demonstrate the right and wrong way to delete a directory in Java. 

The method which accepts a String argument, first print all contents of directory without printing contents of sub directory and then just call delete method on the directory we want to delete. This method cannot remove a non-empty directory, so it failed and return false which is captured in method.  

The right way to delete a directory with files is to recursively delete any sub directory and files inside it, which is demonstrated in deleteDirectory(File) method. 

This method first check if the given File instance represent a directory, if yes then it list all files and sub directory and recursively call the same method to delete each of them. This allows program to remove files inside a sub folder before removing it. Once everything inside given directory is deleted, it proceed to delete the given folder. 

import java.io.File;

/**
* Java Program to delete directory with sub directories and files on it 
* In this example, we have a directory tree as one/ abc.txt
* two/ cde.txt and we will try to delete top level directory one here.
*
* @author Javin Paul
*/
public class FileDeleteDemo {

    public static void main(String args[]) {

        deleteDirectory("one"); // wrong way to remove a directory in Java
        deleteDirectory(new File("one")); 
               //right way to remove directory in Java                              

    }

    /*
     * Right way to delete a non empty directory in Java
    */
    public static boolean deleteDirectory(File dir) {
        if (dir.isDirectory()) {
            File[] children = dir.listFiles();
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDirectory(children[i]);
                if (!success) {
                    return false;
                }
            }
        }

        // either file or an empty directory
        System.out.println("removing file or directory : " 
          + dir.getName());
        return dir.delete();
    }

    /*
     * Incorrect way to delete a directory in Java
     */
    public static void deleteDirectory(String file) {
        File directory = new File(file);
        File[] children = directory.listFiles();
        for (File child : children) {
            System.out.println(child.getAbsolutePath());
        }

        // let's delete this directory
        // it will not work because directory has sub-directory
        // which has files inside it.
        // In order to delete a directory,
        // you need to first delete its files or contents.
        boolean result = directory.delete();
        if (result) {
            System.out.printf("Directory '%s' is successfully deleted",
                                directory.getAbsolutePath());
        } else {
            System.out.printf("Failed to delete directory '%s' %n",
                                directory.getAbsolutePath());
        }
    }
}
D:\Programs\Test\one\abc.txt
D:\Programs\Test\one\two
Failed to delete directory 'D:\Programs\Test\one'
removing file or directory : abc.txt
removing file or directory : cde.txt
removing file or directory : two
removing file or directory : one


That's all on how to delete non-empty directory with files in Java. As you can see in output the method which takes String path is not able to delete our directory with files "one", instead it failed, while our second method has recursively deleted everything inside this top-level directory, you can see files are deleted before directory to make them empty. 

I have not tested this code heavily but it should work on all Java versions starting from Java 1.2

If you like this Java IO tutorial, you will also find following related tutorial interesting and informative :
  • How to read File in one line in Java 8? (example)
  • How to read Microsoft XLS file in Java? (example)
  • How to work with RandomAccessFile in Java? (demo)
  • How to create File and Directory in Java? (solution)
  • How to read/write text files in Java? (solution)
  • How to read/write Properties files in Java? (example)
  • How to read File line by line in Java using BufferedReader? (example)
  • How to use Memory Mapped File in Java? (code)
  • How to make hidden file in Java? (program)
  • How to copy File in Java? (solution)
  • How to check File Permission in Java? (program)
  • Difference between getPath(), getCannonicalPath() and getAbsolutePath() in Java? (answer)
  • How to change File Permission in Java? (solution)
  • Right way to Read Zip Files in Java (example)
  • How to check hidden file in Java? (solution)
P. S. -  It is not using any JDK 7 method like Files.delete()  or  Files.deleteIfExists()  so you can use it with Java 1.5 and Java 1.6 as well. Just remember that you cannot delete a folder with files in Java without removing everything inside it.

And, now is quiz time - What is difference File and Path class in Java? File is from old IO package and Path is from NIO package 

4 comments :

SARAL SAXENA said...

@javin just want to add..Java 7 added support for walking directories with symlink handling
import java.nio.file.*;

public static void removeRecursive(Path path) throws IOException
{
Files.walkFileTree(path, new SimpleFileVisitor()
{
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException
{
Files.delete(file);
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException
{
// try to delete the file anyway, even if its attributes
// could not be read, since delete-only access is
// theoretically possible
Files.delete(file);
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException
{
if (exc == null)
{
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
else
{
// directory iteration failed; propagate exception
throw exc;
}
}
});
}

javin paul said...

@Saral, thanks. Indeed Java 7 has added support to visit files based upon visitor pattern, which could be used to recursively copy, move or delete non empty directories in Java. Thanks for sample program.

nehem said...

Hello sir,
Thanks for letting me know about removing a non empty directory.
I still can't understand one part in this. I hope you would explain me that.
What exactly does the below lines of code do??

for (int i = 0; i < children.length; i++) { boolean success = deleteDirectory(children[i]); if (!success) { return false; }

Thanks again,
Praveen.

javin paul said...

Hello Praveen, its going through each sub-directory and deleting it, if it cannot delete a sub-directory, may be because it is opened by another program then it abort to delete the parent directory.

Post a Comment