Delete a directory tree

When you delete a directory tree: If the deletion operation follows symbolic links, then the file to which the link points is also deleted, in addition to the link itself. Most of the time, you likely want to avoid that.

Example

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Comparator;
import java.util.Objects;
import java.util.stream.Stream;

/** 
 Delete a tree of files.
 
 On Windows, use 'mklink' to create a symlink, if you wish to 
 test the behaviour.
*/
public final class RemoveDirTree {
  
  /**
   Here, 'reverseOrder' is used to replace the natural 
   sort order of File objects. This avoids the possibility of trying
   to delete non-empty dir's.
   @since Java 8 
  */
  void rmDirWithStreams(Path dir) throws IOException {
    //Stream<Path> talks to the file-sys: it needs to be closed, so 
    //we use a try-with-resources block
    //Files.walk(dir, FileVisitOption.FOLLOW_LINKS) // dangerous!
    if (shouldDelete(dir)){
      try(Stream<Path> paths = Files.walk(dir)){
        paths
          .map(Path::toFile) // change to a Stream<File> 
          .sorted(Comparator.reverseOrder()) //put dir's last 
          .forEach(File::delete) // delete it
        ;
      }
    }
  }
  
  /** 
   This style allows for more variations, because the file-walk 
   mechanism is more fine-grained.
   
   If you want to follow symbolic links (more dangerous), use this method: 
   Files.walkFileTree(
     Path start, Set<FileVisitOption> opts, int depth, FileVisitor visitor
   );
   along with:
   EnumSet<FileVisitOption> opts = EnumSet.of(FOLLOW_LINKS);

   Ref: https://docs.oracle.com/javase/tutorial/essential/io/walk.html
   @since Java 7 
  */
  void rmDirWithFileVisitor(Path dir) throws IOException {
    if (shouldDelete(dir)){
      Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
        /** Delete the files in a dir (but not the dir itself). */ 
        @Override public FileVisitResult visitFile(
            Path file, BasicFileAttributes attrs
         ) throws IOException {
            Files.delete(file);
            return FileVisitResult.CONTINUE;
        }
        /** 
         After all the files in the dir are gone, then delete the dir itself. 
        */
        @Override public FileVisitResult postVisitDirectory(
          Path dir, IOException exc
        ) throws IOException {
            Files.delete(dir);
            return FileVisitResult.CONTINUE;
        }
      });
    }
  }
  
  /** Simple test harness. */
  public static void main(String... args) throws IOException {
    RemoveDirTree test = new RemoveDirTree();
    String dirToDelete = "C:\\temp\\testme\\"; //Careful!
    //test.rmDirWithStreams(Paths.get(root));
    test.rmDirWithFileVisitor(Paths.get(dirToDelete));
    log("Done");
  }
  
 private boolean shouldDelete(Path dir){
    return dir.toFile().exists() && dir.toFile().isDirectory();
  }
  
  private static void log(Object thing) {
    System.out.println(Objects.toString(thing));
  }
} 

See Also :
Copy a directory tree