«1. Обзор

Временные каталоги пригодятся, когда нам нужно создать набор файлов, которые мы можем позже отбросить. Когда мы создаем временные каталоги, мы можем делегировать операционной системе, куда их поместить, или указать самим, где мы хотим их разместить.

В этом коротком руководстве мы узнаем, как создавать временные каталоги в Java, используя различные API и подходы. Все примеры в этом руководстве будут выполняться с использованием простой Java 7+, Guava и Apache Commons IO.

2. Делегирование операционной системе

Один из наиболее популярных подходов, используемых для создания временных каталогов, заключается в делегировании места назначения базовой операционной системе. Местоположение задается свойством java.io.tmpdir, и каждая операционная система имеет свою собственную структуру и процедуры очистки.

В простой Java мы создаем каталог, указав префикс, который мы хотим, чтобы каталог принимал:

String tmpdir = Files.createTempDirectory("tmpDirPrefix").toFile().getAbsolutePath();
String tmpDirsLocation = System.getProperty("java.io.tmpdir");
assertThat(tmpdir).startsWith(tmpDirsLocation);

При использовании Guava процесс аналогичен, но мы не можем указать, какой префикс мы хотим использовать для нашего каталога:

String tmpdir = Files.createTempDir().getAbsolutePath();
String tmpDirsLocation = System.getProperty("java.io.tmpdir");
assertThat(tmpdir).startsWith(tmpDirsLocation);

Apache Commons IO не позволяет создавать временные каталоги. Он предоставляет оболочку для получения временного каталога операционной системы, а затем мы должны сделать все остальное:

String tmpDirsLocation = System.getProperty("java.io.tmpdir");
Path path = Paths.get(FileUtils.getTempDirectory().getAbsolutePath(), UUID.randomUUID().toString());
String tmpdir = Files.createDirectories(path).toFile().getAbsolutePath();
assertThat(tmpdir).startsWith(tmpDirsLocation);

Чтобы избежать конфликтов имен с существующими каталогами, мы используем UUID.randomUUID() для создания каталог со случайным именем.

3. Указание местоположения

Иногда нам нужно указать, где мы хотим создать наш временный каталог. Хороший пример — во время сборки Maven. Поскольку у нас уже есть «временный» целевой каталог сборки, мы можем использовать этот каталог для размещения временных каталогов, которые могут понадобиться нашей сборке:

Path tmpdir = Files.createTempDirectory(Paths.get("target"), "tmpDirPrefix");
assertThat(tmpdir.toFile().getPath()).startsWith("target");

И в Guava, и в Apache Commons IO отсутствуют методы для создания временных каталогов в определенных местах. .

Стоит отметить, что целевой каталог может отличаться в зависимости от конфигурации сборки. Один из способов сделать его пуленепробиваемым — передать местоположение целевого каталога JVM, выполняющей тест.

Поскольку операционная система не заботится об очистке, мы можем использовать File.deleteOnExit():

tmpdir.toFile().deleteOnExit();

Таким образом, файл удаляется после завершения JVM, но только если завершение изящно.

4. Использование различных атрибутов файла

Как и для любого другого файла или каталога, при создании временного каталога можно указать атрибуты файла. Таким образом, если мы хотим создать временный каталог, который может читать только создавший его пользователь, мы можем указать набор атрибутов, которые позволят это сделать:

FileAttribute<Set> attrs = PosixFilePermissions.asFileAttribute(
  PosixFilePermissions.fromString("r--------"));
Path tmpdir = Files.createTempDirectory(Paths.get("target"), "tmpDirPrefix", attrs);
assertThat(tmpdir.toFile().getPath()).startsWith("target");
assertThat(tmpdir.toFile().canWrite()).isFalse();

Как и ожидалось, Guava и Apache Commons IO этого не делают. предоставить способ указать атрибуты при создании временных каталогов.

Также стоит отметить, что в предыдущем примере предполагается, что мы находимся в файловой системе, совместимой с Posix, такой как Unix или macOS.

Дополнительную информацию об атрибутах файлов можно найти в нашем Руководстве по API атрибутов файлов NIO2.

5. Заключение

В этом коротком руководстве мы рассмотрели, как создавать временные каталоги в простой Java 7+, Guava и Apache Commons IO. Мы увидели, что обычная Java — наиболее гибкий способ создания временных каталогов, поскольку он предлагает более широкий спектр возможностей, сводя к минимуму многословие.

Как обычно, весь исходный код этого руководства доступен на GitHub.