Jika Anda menggunakan JDK 7 gunakan kelas Files.createTempDirectory baru untuk membuat direktori sementara.
Path tempDirWithPrefix = Files.createTempDirectory(prefix);
Sebelum JDK 7 ini harus dilakukan:
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);
}
Anda bisa membuat pengecualian yang lebih baik (subkelas IOException) jika Anda mau.
temp.delete(); temp = new File(temp.getPath + ".d"); temp.mkdir(); ..., temp.delete();
.delete()
danmkdir()
: Sementara itu, proses jahat dapat membuat direktori target (mengambil nama file yang baru dibuat). LihatFiles.createTempDir()
alternatifnya.Pustaka Google Guava memiliki banyak utilitas bermanfaat. Salah satu catatan di sini adalah kelas Files . Ini memiliki banyak metode yang berguna termasuk:
Ini melakukan persis apa yang Anda minta dalam satu baris. Jika Anda membaca dokumentasi di sini Anda akan melihat bahwa adaptasi yang diusulkan
File.createTempFile("install", "dir")
biasanya menimbulkan kerentanan keamanan.sumber
Jika Anda memerlukan direktori sementara untuk pengujian dan Anda menggunakan jUnit,
@Rule
bersama denganTemporaryFolder
memecahkan masalah Anda:Dari dokumentasi :
Memperbarui:
Jika Anda menggunakan JUnit Jupiter (versi 5.1.1 atau lebih tinggi), Anda memiliki opsi untuk menggunakan JUnit Pioneer yang merupakan Paket Ekstensi JUnit 5.
Disalin dari dokumentasi proyek :
Info selengkapnya di JavaDoc dan JavaDoc dari TempDirectory
Gradle:
Maven:
Pembaruan 2:
The @TempDir penjelasan ditambahkan ke JUnit Jupiter 5.4.0 rilis sebagai fitur eksperimental. Contoh disalin dari Panduan Pengguna JUnit 5 :
sumber
Kode yang ditulis secara naif untuk mengatasi masalah ini menderita kondisi lomba, termasuk beberapa jawaban di sini. Secara historis Anda dapat berpikir dengan hati-hati tentang kondisi balapan dan menulisnya sendiri, atau Anda dapat menggunakan perpustakaan pihak ketiga seperti Google Guava (seperti yang disarankan oleh Spina.) Atau Anda dapat menulis kode kereta.
Tetapi pada JDK 7, ada kabar baik! Pustaka standar Java sendiri sekarang menyediakan solusi yang berfungsi dengan baik (non-bersemangat) untuk masalah ini. Anda ingin java.nio.file.Files # createTempDirectory () . Dari dokumentasi :
Ini secara efektif menyelesaikan laporan bug kuno yang memalukan di pelacak bug Sun yang meminta fungsi seperti itu.
sumber
Ini adalah kode sumber ke Files.createTempDir () perpustakaan perpustakaan. Ini tidak serumit yang Anda kira:
Secara default:
Lihat disini
sumber
Jangan gunakan
deleteOnExit()
bahkan jika Anda secara eksplisit menghapusnya nanti.Google 'deleteonexit is evil' untuk info lebih lanjut, tetapi inti masalahnya adalah:
deleteOnExit()
hanya menghapus untuk shutdown JVM normal, tidak crash atau membunuh proses JVM.deleteOnExit()
hanya menghapus JVM shutdown - tidak bagus untuk proses server yang berjalan lama karena:Yang paling jahat dari semuanya -
deleteOnExit()
menghabiskan memori untuk setiap entri file temp. Jika proses Anda berjalan selama berbulan-bulan, atau membuat banyak file temp dalam waktu singkat, Anda menggunakan memori dan tidak pernah melepaskannya sampai JVM dimatikan.sumber
Pada Java 1.7
createTempDirectory(prefix, attrs)
dancreateTempDirectory(dir, prefix, attrs)
termasuk dalamjava.nio.file.Files
Contoh:
File tempDir = Files.createTempDirectory("foobar").toFile();
sumber
Inilah yang saya putuskan untuk lakukan untuk kode saya sendiri:
sumber
Yah, "createTempFile" sebenarnya membuat file. Jadi mengapa tidak hapus saja dulu, lalu lakukan mkdir di atasnya?
sumber
Kode ini harus bekerja dengan cukup baik:
sumber
Seperti dibahas dalam RFE ini dan komentarnya, Anda dapat menelepon
tempDir.delete()
terlebih dahulu. Atau Anda bisa menggunakanSystem.getProperty("java.io.tmpdir")
dan membuat direktori di sana. Bagaimanapun, Anda harus ingat untuk menelepontempDir.deleteOnExit()
, atau file tidak akan dihapus setelah Anda selesai.sumber
Hanya untuk penyelesaian, ini adalah kode dari perpustakaan google jambu. Ini bukan kode saya, tapi saya pikir sangat berharga untuk menunjukkannya di sini di utas ini.
sumber
Saya mendapat masalah yang sama jadi ini hanyalah jawaban lain bagi mereka yang tertarik, dan ini mirip dengan salah satu di atas:
Dan untuk aplikasi saya, saya memutuskan untuk menambahkan opsi untuk menghapus temp pada saat keluar jadi saya menambahkan di hook-down:
Metode menghapus semua subdir dan file sebelum menghapus temp , tanpa menggunakan callstack (yang benar-benar opsional dan Anda bisa melakukannya dengan rekursi pada titik ini), tetapi saya ingin berada di sisi yang aman.
sumber
Seperti yang Anda lihat di jawaban lain, tidak ada pendekatan standar yang muncul. Karena itu Anda sudah menyebut Apache Commons, saya mengusulkan pendekatan berikut menggunakan FileUtils dari Apache Commons IO :
Ini lebih disukai karena apache commons perpustakaan yang datang paling dekat dengan "standar" yang diminta dan bekerja dengan JDK 7 dan versi yang lebih lama. Ini juga mengembalikan contoh File "lama" (yang berbasis aliran) dan bukan contoh Path "baru" (yang berbasis buffer dan akan menjadi hasil dari metode getTemporaryDirectory () JDK7) -> Karena itu ia mengembalikan apa yang dibutuhkan kebanyakan orang saat mereka ingin membuat direktori sementara.
sumber
Saya suka beberapa upaya membuat nama yang unik tetapi bahkan solusi ini tidak mengesampingkan kondisi balapan. Proses lain dapat menyelinap masuk setelah tes untuk
exists()
danif(newTempDir.mkdirs())
metode doa Saya tidak tahu bagaimana membuat ini sepenuhnya aman tanpa menggunakan kode asli, yang saya kira adalah apa yang terkubur di dalamnyaFile.createTempFile()
.sumber
Sebelum Java 7 Anda juga bisa:
sumber
Coba contoh kecil ini:
Kode:
Impor:
java.io.IOException
java.nio.file.Files
java.nio.file.Path
Output konsol pada mesin Windows:
C: \ Users \ userName \ AppData \ Local \ Temp \ tmpDir2908538301081367877
Komentar:
Files.createTempDirectory menghasilkan ID unik secara otomatis - 2908538301081367877.
Catatan:
Baca berikut ini untuk menghapus direktori secara berulang :
Hapus direktori secara rekursif di Jawa
sumber
Menggunakan
File#createTempFile
dandelete
membuat nama unik untuk direktori tampaknya ok. Anda harus menambahkanShutdownHook
untuk menghapus direktori (secara rekursif) pada JVM shutdown.sumber