Delete directory with contents in Java

Removing empty directory in Java is as simple as calling File.delete() (standard IO) or Files.delete() (NIO) method. However, if the folder is not empty (for example contains one or more files or subdirectories), these methods will refuse to remove it. In this post I want to present few ways to recursively remove the directory together with its contents.

Standard recursion (Java 6 and before)

The first method recursively removes files and directories from the directory tree starting from the leaves. Because it uses old I/O class File for operating on files and directories, this method can be used in any Java version.

void deleteDirectoryRecursionJava6(File file) throws IOException {
  if (file.isDirectory()) {
    File[] entries = file.listFiles();
    if (entries != null) {
      for (File entry : entries) {
        deleteDirectoryRecursionJava6(entry);
      }
    }
  }
  if (!file.delete()) {
    throw new IOException("Failed to delete " + file);
  }
}

Standard recursion using NIO (since Java 7)

Java 7 introduced improved API for I/O operations (also known as NIO). Once we decide to use it, the first method can be changed as follows:

void deleteDirectoryRecursion(Path path) throws IOException {
  if (Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
    try (DirectoryStream<Path> entries = Files.newDirectoryStream(path)) {
      for (Path entry : entries) {
        deleteDirectoryRecursion(entry);
      }
    }
  }
  Files.delete(path);
}

Walk tree (since Java 7)

Additionally, Java 7 introduced new method Files.walkFileTree() which traverses directory tree in the file-system using visitor design pattern. This new method can be easily used to recursively delete directory:

void deleteDirectoryWalkTree(Path path) throws IOException {
  FileVisitor visitor = new SimpleFileVisitor<Path>() {
            
    @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 {
      Files.delete(file);
      return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
      if (exc != null) {
        throw exc;
      }
      Files.delete(dir);
      return FileVisitResult.CONTINUE;
    }
  };
  Files.walkFileTree(path, visitor);
}

Streams and NIO2 (since Java 8)

Since Java 8 we can use Files.walk() method which behaves like this according to the official documentation:

Return a Stream that is lazily populated with Path by walking the file tree rooted at a given starting file. The file tree is traversed depth-first, the elements in the stream are Path objects that are obtained as if by resolving the relative path against start.

The stream has to be sorted in reverse order first to prevent removal of non-empty directory. The final code looks like this:

void deleteDirectoryStream(Path path) throws IOException {
  Files.walk(path)
    .sorted(Comparator.reverseOrder())
    .map(Path::toFile)
    .forEach(File::delete);
}

However, this code has two drawbacks:

  • The stream is being sorted so all stream elements must be present in memory at the same time. This may significantly increase memory consumption for deep directory trees.
  • There is no error handling because the return value from File.delete() is ignored. This can be improved by using custom lambda inside forEach().

Apache Commons IO

Finally, there is a one-liner solution for the impatient. Just add Maven dependency:

<dependency>
   <groupId>commons-io</groupId>
   <artifactId>commons-io</artifactId>
   <version>2.6</version>
</dependency>

and call this single method:

FileUtils.deleteDirectory(file);

That’s all.

Conclusion

All of above methods should do the job. Personally, I prefer the last one because it is the simplest to use. The source code is available at GitHub.

Advertisements

About Robert Piasecki

Husband and father, Java software developer, Linux and open-source fan.
This entry was posted in Java, Maven, Uncategorized and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s