'Does Files.createTempDirectory remove the directory after JVM exits normally?

Does Files.createTempDirectory remove the directory after JVM exits normally? Or do I need to manually recursively remove the temporary directory content?



Solution 1:[1]

Temporary directories created by Files.createTempDirectory() are not deleted upon system exit (JVM termination), unless you configure them to do so:

A shutdown-hook, or the File.deleteOnExit() mechanism may be used to delete the directory automatically.

Meaning you could call:

Path tmp = Files.createTempDirectory(null);
tmp.toFile().deleteOnExit();

However you cannot delete a directory unless it's empty, as document by File.delete():

Deletes the file or directory denoted by this abstract pathname. If this pathname denotes a directory, then the directory must be empty in order to be deleted.

So we need to get a bit fancier if you want the directory and its contents deleted. You can recursively register a directory and its children for deletion like so:

public static void recursiveDeleteOnExit(Path path) throws IOException {
  Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file,
        @SuppressWarnings("unused") BasicFileAttributes attrs) {
      file.toFile().deleteOnExit();
      return FileVisitResult.CONTINUE;
    }
    @Override
    public FileVisitResult preVisitDirectory(Path dir,
        @SuppressWarnings("unused") BasicFileAttributes attrs) {
      dir.toFile().deleteOnExit();
      return FileVisitResult.CONTINUE;
    }
  });
}

Take note however, this registers all currently existing files for deletion - if after calling this method you create new files, they and their parent directories will not be deleted per the documented behavior of File.delete().

If you want to delete a directory upon exit, regardless of the contents of said directory, you can use a shutdown-hook in an almost identical manner:

public static void recursiveDeleteOnShutdownHook(final Path path) {
  Runtime.getRuntime().addShutdownHook(new Thread(
    new Runnable() {
      @Override
      public void run() {
        try {
          Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file,
                @SuppressWarnings("unused") BasicFileAttributes attrs)
                throws IOException {
              Files.delete(file);
              return FileVisitResult.CONTINUE;
        }
        @Override
        public FileVisitResult postVisitDirectory(Path dir, IOException e)
            throws IOException {
          if (e == null) {
            Files.delete(dir);
            return FileVisitResult.CONTINUE;
          }
          // directory iteration failed
          throw e;
        }
        });
      } catch (IOException e) {
        throw new RuntimeException("Failed to delete "+path, e);
      }
    }}));
}

Note however that calling this repeatedly registers a new shutdown thread each time, which could potentially cause problems at scale. File.deleteOnExit() stores a set of registered files, and deletes all of them in one shutdown hook. If you need to delete many directories in this manner, you'd want to implement something similar.

Solution 2:[2]

You can add apache commons io dependency to your project and then use FileUtils.deleteDirectory() to do something like:

Runtime.getRuntime().addShutdownHook(new Thread() {
    @Override
    public void run() {
        try {
            FileUtils.deleteDirectory(tmp_dir_path.toFile());
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
});

For more information about apache commons check: https://commons.apache.org/proper/commons-io/

Solution 3:[3]

No it doesn't - createTempDirectory

As with the createTempFile methods, this method is only part of a temporary-file facility. A shutdown-hook, or the File.deleteOnExit() mechanism may be used to delete the directory automatically.

Solution 4:[4]

No, it doesn't. You have to do it on your own. Or use java.io.File.deleteOnExit() but I guess it doesn't work for non-empty directories

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 JohnK
Solution 2 SiKing
Solution 3
Solution 4 Adam Dyga