Если вы используете JDK 7, используйте новый класс Files.createTempDirectory для создания временного каталога.
Path tempDirWithPrefix = Files.createTempDirectory(prefix);
Перед JDK 7 это должно сделать это:
public static File createTempDirectory()
throws IOException
{
final File temp;
temp = File.createTempFile("temp", Long.toString(System.nanoTime()));
if(!(temp.delete()))
{
throw new IOException("Could not delete temp file: " + temp.getAbsolutePath());
}
if(!(temp.mkdir()))
{
throw new IOException("Could not create temp directory: " + temp.getAbsolutePath());
}
return (temp);
}
Вы можете сделать лучшие исключения (подкласс IOException), если хотите.
temp.delete(); temp = new File(temp.getPath + ".d"); temp.mkdir(); ..., temp.delete();
.delete()
иmkdir()
: В то же время злонамеренный процесс может создать целевой каталог (принимая имя недавно созданного файла). СмотритеFiles.createTempDir()
для альтернативы.В библиотеке Google Guava есть множество полезных утилит. Одним из примечаний здесь является класс Files . У него есть куча полезных методов, в том числе:
Это делает именно то, что вы просили в одной строке. Если вы прочитаете здесь документацию, то увидите, что предлагаемая адаптация
File.createTempFile("install", "dir")
обычно представляет уязвимости безопасности.источник
Если вам нужен временный каталог для тестирования и вы используете jUnit,
@Rule
вместе сTemporaryFolder
решает вашу проблему:Из документации :
Обновить:
Если вы используете JUnit Jupiter (версия 5.1.1 или выше), у вас есть возможность использовать JUnit Pioneer, который является пакетом расширений JUnit 5.
Скопировано из проектной документации :
Больше информации в JavaDoc и JavaDoc TempDirectory
Gradle:
Maven:
Обновление 2:
@TempDir аннотаций была добавлена в JUnit Jupiter 5.4.0 выпуска в качестве экспериментальной функции. Пример, скопированный из Руководства пользователя JUnit 5 :
источник
Наивно написанный код для решения этой проблемы страдает от условий гонки, в том числе несколько ответов здесь. Исторически сложилось так, что вы могли тщательно обдумать условия гонки и написать ее самостоятельно, или вы могли бы использовать стороннюю библиотеку, такую как Google Guava (как подсказал ответ Спины). Или вы могли бы написать глючный код.
Но с JDK 7 есть хорошие новости! Сама стандартная библиотека Java теперь предоставляет правильно работающее (нерасовое) решение этой проблемы. Вы хотите java.nio.file.Files # createTempDirectory () . Из документации :
Это эффективно разрешает неловко древний отчет об ошибках в трекере ошибок Sun, который запрашивал именно такую функцию.
источник
Это исходный код для Files.createTempDir () библиотеки Guava. Это нигде не так сложно, как вы думаете
По умолчанию:
Посмотреть здесь
источник
Не используйте,
deleteOnExit()
даже если вы явно удалите его позже.Google «deleteonexit is evil» для получения дополнительной информации, но суть проблемы заключается в следующем:
deleteOnExit()
удаляет только для нормальных завершений JVM, а не для сбоев или уничтожения процесса JVM.deleteOnExit()
удаляет только при завершении работы JVM - не подходит для длительных процессов сервера, потому что:Самое злое из всех -
deleteOnExit()
потребляет память для каждой записи временного файла. Если ваш процесс выполняется месяцами или создает много временных файлов за короткое время, вы расходуете память и никогда не освобождаете ее, пока JVM не отключится.источник
Начиная с Java 1.7
createTempDirectory(prefix, attrs)
иcreateTempDirectory(dir, prefix, attrs)
включены вjava.nio.file.Files
Пример:
File tempDir = Files.createTempDirectory("foobar").toFile();
источник
Вот что я решил сделать для моего собственного кода:
источник
Ну, «createTempFile» фактически создает файл. Так почему бы просто не удалить его сначала, а затем сделать на нем mkdir?
источник
Этот код должен работать достаточно хорошо:
источник
Как уже говорилось в этом RFE и его комментариях, вы можете позвонить
tempDir.delete()
первым. Или вы можете использоватьSystem.getProperty("java.io.tmpdir")
и создать каталог там. В любом случае, вы должны помнить, чтобы позвонитьtempDir.deleteOnExit()
, или файл не будет удален после того, как вы закончите.источник
Просто для завершения, это код из библиотеки Google Guava. Это не мой код, но я думаю, что стоит показать его здесь, в этой теме.
источник
У меня та же проблема, так что это просто еще один ответ для тех, кто заинтересован, и он похож на один из вышеперечисленных:
И для моего приложения я решил добавить опцию для очистки временного интервала при выходе, поэтому я добавил в ловушку выключения:
Метод удаляет все подкаталоги и файлы перед удалением temp , без использования callstack (что совершенно необязательно, и вы можете сделать это с рекурсией на этом этапе), но я хочу быть на безопасной стороне.
источник
Как видно из других ответов, стандартного подхода не возникло. Следовательно, вы уже упомянули Apache Commons, я предлагаю следующий подход с использованием FileUtils из Apache Commons IO :
Это предпочтительнее, поскольку apache объединяет библиотеку, которая наиболее близка к запрашиваемому «стандарту» и работает как с JDK 7, так и с более старыми версиями. Это также возвращает «старый» экземпляр File (основанный на потоке), а не «новый» экземпляр Path (основанный на буфере и являющийся результатом метода getDeventDirectory ()) JDK7 -> Поэтому он возвращает то, что нужно большинству людей, когда они хотят создать временный каталог.
источник
Мне нравятся многочисленные попытки создания уникального имени, но даже это решение не исключает условия гонки. Другой процесс может проскочить после проверки
exists()
иif(newTempDir.mkdirs())
вызова метода. Я понятия не имею, как полностью сделать это безопасным, не прибегая к нативному коду, который, как я предполагаю, является тем, что скрыто внутриFile.createTempFile()
.источник
До Java 7 вы также могли:
источник
Попробуйте этот небольшой пример:
Код:
Импорт:
java.io.IOException
java.nio.file.Files
java.nio.file.Path
Вывод на консоль на компьютере Windows:
C: \ Users \ имя_пользователя \ AppData \ Local \ Temp \ tmpDir2908538301081367877
Комментарий:
Files.createTempDirectory автоматически генерирует уникальный идентификатор - 2908538301081367877.
Примечание.
Прочитайте следующее для рекурсивного удаления каталогов: рекурсивное
удаление каталогов в Java
источник
Использование
File#createTempFile
иdelete
для создания уникального имени для каталога кажется нормальным. Вы должны добавить,ShutdownHook
чтобы (рекурсивно) удалить каталог при завершении работы JVM.источник