Working With Temporary Files/Folders in Java
Join the DZone community and get the full member experience.
Join For FreeThe Java NIO.2 API provides support for working with temporary folders/files. For example, we can easily locate the default location for temporary folders/files as follows:
String defaultBaseDir = System.getProperty("java.io.tmpdir");
Commonly, in Windows, the default temporary folder is C:\Temp
, %Windows%\Temp
, or a temporary directory per user in Local Settings\Temp
(this location is usually controlled via the TEMP
environment variable).
In Linux/Unix, the global temporary directories are /tmp
and /var/tmp
. The preceding line of code will return the default location, depending on the operating system. Next, we'll learn how to create a temporary folder/file.
You may also like: Practical Guide for Converting Between Date and Temporal
Creating a Temporary Folder/File
Creating a temporary folder can be accomplished using:
Path createTempDirectory (Path dir, String prefix, FileAttribute<?>... attrs)
This is a static
method in the Files
class that can be used as follows:
- Let's create a temporary folder in the OS's default location with no prefix:
xxxxxxxxxx
// C:\Users\Anghel\AppData\Local\Temp\8083202661590940905
Path tmpNoPrefix = Files.createTempDirectory(null);
- Let's create a temporary folder in the OS's default location with a custom prefix:
xxxxxxxxxx
// C:\Users\Anghel\AppData\Local\Temp\logs_5825861687219258744
String customDirPrefix = "logs_";
Path tmpCustomPrefix = Files.createTempDirectory(customDirPrefix);
- Let's create a temporary folder in a custom location with a custom prefix:
xxxxxxxxxx
// D:\tmp\logs_10153083118282372419
Path customBaseDir = FileSystems.getDefault().getPath("D:/tmp");
String customDirPrefix = "logs_";
Path tmpCustomLocationAndPrefix = Files.createTempDirectory(customBaseDir, customDirPrefix);
Creating a temporary file can be accomplished via:
Path createTempFile (Path dir, String prefix, String suffix, FileAttribute<?>... attrs
This is a static
method in the Files
class that can be used as follows:
- Let's create a temporary file in the OS's default location with no prefix and suffix:
xxxxxxxxxx
// C:\Users\Anghel\AppData\Local\Temp\16106384687161465188.tmp
Path tmpNoPrefixSuffix = Files.createTempFile(null, null);
- Let's create a temporary file in the OS's default location with a custom prefix and suffix:
xxxxxxxxxx
// C:\Users\Anghel\AppData\Local\Temp\log_402507375350226.txt
String customFilePrefix = "log_";
String customFileSuffix = ".txt";
Path tmpCustomPrefixAndSuffix = Files.createTempFile(customFilePrefix, customFileSuffix);
- Let's create a temporary file in a custom location with a custom prefix and suffix:
xxxxxxxxxx
// D:\tmp\log_13299365648984256372.txt
Path customBaseDir = FileSystems.getDefault().getPath("D:/tmp");
String customFilePrefix = "log_";
String customFileSuffix = ".txt";
Path tmpCustomLocationPrefixSuffix
= Files.createTempFile(customBaseDir, customFilePrefix, customFileSuffix);
Next, we'll take a look at the different ways we can delete a temporary folder/file.
Deleting a Temporary Folder/File Via Shutdown-Hook
Deleting a temporary folder/file is a task that can be accomplished by the operating system or specialized tools. However, sometimes, we need to control this programmatically and delete a folder/file based on different design considerations.
A solution to this problem relies on the shutdown-hook mechanism, which can be implemented via the Runtime.getRuntime().addShutdownHook()
method. This mechanism is useful whenever we need to complete certain tasks (for example, cleanup tasks) right before the JVM shuts down. It is implemented as a Java thread whose run()
method is invoked when the shutdown-hook is executed by JVM at shut down. This is shown in the following code:
xxxxxxxxxx
Path customBaseDir = FileSystems.getDefault().getPath("D:/tmp");
String customDirPrefix = "logs_";
String customFilePrefix = "log_";
String customFileSuffix = ".txt";
try {
Path tmpDir = Files.createTempDirectory(customBaseDir, customDirPrefix);
Path tmpFile1 = Files.createTempFile(tmpDir, customFilePrefix, customFileSuffix);
Path tmpFile2 = Files.createTempFile(tmpDir, customFilePrefix, customFileSuffix);
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try (DirectoryStream<Path> ds = Files.newDirectoryStream(tmpDir)) {
for (Path file: ds) {
Files.delete(file);
}
Files.delete(tmpDir);
} catch (IOException e) {
...
}
}
});
//simulate some operations with temp file until delete it
Thread.sleep(10000);
} catch (IOException | InterruptedException e) {
...
}
A shutdown-hook will not be executed in the case of abnormal/forced terminations (for example, JVM crashes, Terminal operations are triggered, and so on). It runs when all the threads finish or when
System.exit(0)
is called. It is advisable to run it fast since they can be forcibly stopped before completion if something goes wrong (for example, the OS shuts down). Programmatically, a shutdown-hook can only be stopped byRuntime.halt()
.
Deleting a Temporary Folder/File via deleteOnExit()
Another solution for deleting a temporary folder/file relies on the File.deleteOnExit()
method. By calling this method, we can register for the deletion of a folder/file. The deletion action happens when JVM shuts down:
xxxxxxxxxx
Path customBaseDir = FileSystems.getDefault().getPath("D:/tmp");
String customDirPrefix = "logs_";
String customFilePrefix = "log_";
String customFileSuffix = ".txt";
try {
Path tmpDir = Files.createTempDirectory(customBaseDir, customDirPrefix);
System.out.println("Created temp folder as: " + tmpDir);
Path tmpFile1 = Files.createTempFile(tmpDir, customFilePrefix, customFileSuffix);
Path tmpFile2 = Files.createTempFile(tmpDir, customFilePrefix, customFileSuffix);
try (DirectoryStream<Path> ds = Files.newDirectoryStream(tmpDir)) {
tmpDir.toFile().deleteOnExit();
for (Path file: ds) {
file.toFile().deleteOnExit();
}
} catch (IOException e) {
...
}
// simulate some operations with temp file until delete it
Thread.sleep(10000);
} catch (IOException | InterruptedException e) {
...
}
It is advisable to only rely on this method (
deleteOnExit()
) when the application manages a small number of temporary folders/files. This method may consume a lot of memory (it consumes memory for each temporary resource that's registered for deletion) and this memory may not be released until JVM terminates.
Pay attention, since this method needs to be called in order to register each temporary resource, and the deletion takes place in reverse order of registration (for example, we must register a temporary folder before registering its content).
Deleting a Temporary File via DELETE_ON_CLOSE
Another solution when it comes to deleting a temporary file relies on StandardOpenOption.DELETE_ON_CLOSE
(this deletes the file when the stream is closed). For example, the following piece of code creates a temporary file via the createTempFile()
method and opens a buffered writer stream for it with DELETE_ON_CLOSE
explicitly specified:
xxxxxxxxxx
Path customBaseDir = FileSystems.getDefault().getPath("D:/tmp");
String customFilePrefix = "log_";
String customFileSuffix = ".txt";
Path tmpFile = null;
try {
tmpFile = Files.createTempFile(
customBaseDir, customFilePrefix, customFileSuffix);
} catch (IOException e) {
...
}
try (BufferedWriter bw = Files.newBufferedWriter(tmpFile,
StandardCharsets.UTF_8, StandardOpenOption.DELETE_ON_CLOSE)) {
//simulate some operations with temp file until delete it
Thread.sleep(10000);
} catch (IOException | InterruptedException e) {
...
}
This solution can be adopted for any file. It is not specific to temporary resources.
The complete examples are available on GitHub under the prefix P142_foo.
If you enjoyed this article, then you'll love my book, Java Coding Problems, that contains a dedicated chapter including 20 problems dedicated to Java I/O.
Happy coding!
Further Reading
Opinions expressed by DZone contributors are their own.
Comments