В Java создание временного файла может потребоваться во многих сценариях, например, при модульном тестировании, пакетных операциях, загрузке файлов или обработке больших запросов, когда результат промежуточных операций необходимо сохранить для дальнейшего использования.
В этом руководстве по Java рассматриваются несколько простых способов создания временных файлов или каталогов.
Путь tempFile = Files.createTempFile("test-data-", ".txt"); //NIO//tempFile.toFile().deleteOnExit();Файл tempFile = File.createTempFile("test-data-", ".txt") //Устаревший//tempFile.deleteOnExit();Path tempDirectory = Files.createTempDirectory("temp-dir"); //Создать временный каталог//Очистка с помощью хука завершения работы
Если мы собираемся создавать временные файлы/каталоги в модульном тестировании, нам лучше использовать TemporaryFolder(JUnit 4) или @TempDir(JUnit 5). Они позволяют создавать файлы и каталоги, которые гарантированно будут удалены после завершения тестового метода(независимо от того, прошел тест или нет).
1. Расположение временных файлов и каталогов по умолчанию
Важно знать, что если целевое местоположение не указано, временный файл/каталог создается во временном каталоге по умолчанию, указанном системным свойством java.io.tmpdir.
- Windows – %USER%/AppData/Local/Temp/
- Linux или macOS – /tmp/
2. Создание временных файлов
2.1. Использование Files.createTempFile() [Java NIO]
Метод java.nio.file.Files.createTempFile () является перегруженным методом. Оба метода создадут файл только в том случае, если до вызова метода не существовало файла с таким же именем и местоположением.
Путь createTempFile(Префикс строки, Суффикс строки, Атрибут файла<?>... атрибуты)Путь createTempFile(Путь dir, Префикс строки, Суффикс строки, Атрибут файла<?>... attrs)
- dir – каталог, в котором будет создан файл. Если null, будет использовано расположение по умолчанию, как указано в предыдущем разделе.
- префикс – используется при формировании имени файла. Он должен быть длиной не менее трех символов.
- суффикс – используется при формировании имени файла(обычно расширения). Если null, будет использоваться «.tmp».
В приведенном примере созданный временный файл будет удален при завершении работы программы.
Атрибут файла<?>[] атрибуты = {PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-r--r--"))};Путь tempFile = Files.createTempFile(Files.createTempDirectory("temp-dir"), "testData-", ".txt", атрибуты);System.out.println(tempFile.toAbsolutePath().toString());
Вывод программы:
<Путь к временным файлам по умолчанию>\temp-dir10165603645741470295\testData-17461647418384794020.txt
Если мы хотим автоматически удалить временный файл, откройте файл с параметром DELETE_ON_CLOSE, чтобы файл был удален при вызове соответствующего метода close() после того, как мы обработали файл, например, записали данные во временный файл.
Path tempFile;try {tempFile = Files.createTempFile("testData-", ".txt");try(var outputStream = Files.newOutputStream(tempFile, StandardOpenOption.DELETE_ON_CLOSE)) {// Write data to the file or perform operations...}} catch(IOException e) {//...}
В качестве альтернативы для автоматического удаления файла можно использовать shutdown-hook или механизм File.deleteOnExit().
try {tempFile = Files.createTempFile("testData-", ".txt");tempFile.toFile().deleteOnExit();}
2.1. Использование File.createTempFile() [Устаревшая версия]
Этот java.io.File.createTempFile() работает аналогично Files.createTempFile(), как показано в предыдущем примере. Он создает новый пустой временный файл в указанном каталоге, используя заданные строки префикса и суффикса для генерации его имени.
Единственное различие между этими двумя подходами заключается в использовании устаревших классов Java.
Файл createTempFile(String prefix, String suffix) выдает IOExceptionФайл createTempFile(префикс строки, суффикс строки, каталог файла) выдает исключение IOException
Давайте рассмотрим пример.
Файл tempFile;пытаться {tempFile = Файл.createTempFile("testData-", ".txt");System.out.println("Временный файл создан: " + tempFile.getAbsolutePath());}поймать(IOException e) {//...}
Если мы хотим автоматически удалять временный файл при завершении работы виртуальной машины, используйте метод deleteOnExit().
File tempFile;try {tempFile = File.createTempFile("testData-", ".txt");tempFile.deleteOnExit(); //deletes file when the virtual machine terminate//...}
3. Создание временного каталога
Подобно временным файлам, мы можем использовать оба ранее рассмотренных класса для создания временных каталогов:
static Path createTempDirectory(Path dir, String prefix, FileAttribute<?>... attrs) throws IOExceptionstatic Path createTempDirectory(String prefix, FileAttribute<?>... attrs) throws IOException
В простых случаях мы создаем каталог, указывая префикс для имени каталога:
Path tempDir = Files.createTempDirectory("tempDirPrefix-");
В качестве альтернативы мы также можем передать местоположение временного каталога, который будет создан.
Path tmpdir = Files.createTempDirectory(Paths.get("/temp/data/"), "tempDirPrefix-");
Обратите внимание, что Java не удаляет каталог автоматически при выходе из JVM. Если мы хотим, чтобы созданный временный каталог был автоматически удален при выходе из JVM, нам нужно зарегистрировать хук выключения, чтобы позаботиться об очистке.
В следующем примере Files.walk рекурсивно обходит каталог и его содержимое в обратном порядке и удаляет каждый файл и подкаталог.
try {// Create a temporary directoryPath tempDirectory = Files.createTempDirectory("temp-dir");// Register a shutdown hook to delete the directory when the JVM exitsRuntime.getRuntime().addShutdownHook(new Thread(() -> {try {Files.walk(tempDirectory).sorted((p1, p2) -> -p1.compareTo(p2)).forEach(path -> {try {Files.delete(path);} catch(IOException e) {e.printStackTrace();}});} catch(IOException e) {e.printStackTrace();}}));// Do some work with the temporary directory...} catch(IOException e) {e.printStackTrace();}
Помните, что использование хука завершения работы может быть полезным, но оно не может охватить все возможные сценарии(например, принудительное завершение работы JVM).
4. Заключение
В Java использование класса java.nio.file.Files является наилучшим подходом для создания временного файла или временного каталога. Использование любой другой сторонней библиотеки может не принести никаких дополнительных преимуществ.
Важно очистить временные файлы и каталоги, если они были созданы только для хранения промежуточных результатов. Это поможет контролировать размер ОС.