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

- 40,646
- 13
- 77
- 103
6 Answers
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.
-
10In Spring there's a helper method `org.springframework.util.FileSystemUtils.deleteRecursively(File root)` for explicit recursive directory deletion. – Sergey Shcherbakov Jun 21 '17 at 06:48
As per the API, no it doesn't, you need to manually remove the directory, using file.deleteOnExit()
method.
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.

- 8,004
- 8
- 44
- 57

- 17,683
- 18
- 56
- 107
-
Like will this work? `new File(Files.createTempDirectory(null).toString()).deleteOnExit()` – Feb 22 '13 at 10:45
-
2@HowardGuo, I don't think so, you are passing null to createTempDirectory method – Pradeep Simha Feb 22 '13 at 10:49
-
2@HowardGuo, http://docs.oracle.com/javase/tutorial/essential/io/dirs.html this should give you more information – Pradeep Simha Feb 22 '13 at 10:51
-
1
-
1@HowardGuo, no it cannot be :) In the link you can refer example program – Pradeep Simha Feb 22 '13 at 10:55
-
1Am i missing anything here? I thought I read: `prefix - the prefix string to be used in generating the directory's name; may be null` – Feb 22 '13 at 10:57
-
1@HowardGuo, yes prefix maybe null, but not others. If you read API docs, this method accepts 3 arguments and your code won't compile since you are passing only 1 argument – Pradeep Simha Feb 22 '13 at 11:00
-
Thanks. I just tried this piece of code: `val dir = Files.createTempDirectory(null); new File(dir.toString()).deleteOnExit()` it creates the temp directory but does not delete it after JVM exists. guess I have to find another way to delete the dir.. – Feb 22 '13 at 11:03
-
4@PradeepSimha - what makes you say you can't pass `null`? You certainly can call [`Files.createTempDirectory(null)`](http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#createTempDirectory(java.lang.String,%20java.nio.file.attribute.FileAttribute...)), this works exactly as one would expect - it creates a new arbitrarily named directory and returns its Path. – dimo414 Nov 29 '13 at 08:15
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/
-
3Worth noting that this deletes the directory, whether or not it's empty. – Joshua Richardson Dec 04 '17 at 22:25
No it doesn't - createTempDirectory
As with the
createTempFile
methods, this method is only part of a temporary-file facility. A shutdown-hook, or theFile.deleteOnExit()
mechanism may be used to delete the directory automatically.
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

- 8,666
- 4
- 27
- 35
-
3I would love Java more if `new File(Files.createTempDirectory(null).toString()).deleteOnExit()` works, hahaha.. – Feb 22 '13 at 10:44
-
4It works exactly as documented - "the directory must be empty in order to be deleted" - wanting to delete a non-empty directory is reasonable, but don't confuse your desire with "Java doesn't work". – dimo414 Nov 29 '13 at 07:48
If using JUnit 5, the @TempDir
annotation is super nice. It also recursively deletes the created directory when the test or test-class ends (depending on the scope of the annotation).
For example:
@BeforeAll
public static void setup(@TempDir Path tempDir) {
// The dir will be deleted when the class ends, ala @AfterClass
}
Or
@Test
public static void myTest(@TempDir Path tempDir) {
// The dir will be deleted when this test method ends
}

- 1
- 1