Tidak semua berkas layak menyimpan nama: hasil antara proses panjang, unggahan yang belum tervalidasi, cache yang bisa dibangun ulang kapan saja. Untuk data seperti itu Java menyediakan pabrik berkas sementara — Files.createTempFile dan Files.createTempDirectory — yang menempatkan berkas di lokasi khusus sistem operasi dan menjamin namanya tidak bentrok lewat penambahan angka acak. Sisi sulitnya bukan membuat, melainkan menjaga kebersihan: berkas sementara yang tidak pernah dihapus menggunung hingga disk penuh, sementara nama sementara yang mudah ditebak membuka celah keamanan klasik di sistem multi-pengguna. Pada Chapter ini kita belajar membuat, memakai, dan membersihkan berkas sementara secara disiplin.
Membuat Berkas Sementara #
Files.createTempFile(prefix, suffix) membuat berkas kosong di direktori sementara milik sistem operasi — pada Linux biasanya /tmp, yang dikendalikan properti sistem java.io.tmpdir. Nama hasilnya adalah gabungan prefix, angka unik, dan suffix: pemanggilan dengan "catatan-" dan ".txt" menghasilkan nama seperti catatan-8134026014658238412.txt. Angka tengah itu dijamin unik dan tak terduga — JVM mengulang pemilihan nama sampai berhasil membuat berkas yang belum ada, dalam satu langkah atomik yang tidak bisa disusupi proses lain. Varian ketiga argumen createTempFile(direktori, prefix, suffix) menempatkan berkas di direktori pilihan kita, berguna untuk menjaga transfer atomik tetap satu sistem berkas dengan target akhirnya.
Karena nama berkas memang sengaja acak, program contoh kita hanya mencocokkan polanya, bukan mencetak namanya:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class BerkasSementara {
public static void main(String[] args) throws IOException {
Path sementara = Files.createTempFile("catatan-", ".txt");
String nama = sementara.getFileName().toString();
System.out.println("awalan cocok : " + nama.startsWith("catatan-"));
System.out.println("akhiran cocok : " + nama.endsWith(".txt"));
System.out.println("berkas ada : " + Files.exists(sementara));
Files.writeString(sementara, "data sementara");
System.out.println("isi utuh : "
+ Files.readString(sementara).equals("data sementara"));
// Di direktori kerja sendiri: nama tetap dibuat acak.
Path lokal = Files.createTempFile(Path.of("."), "olah-", ".tmp");
System.out.println("lokal cocok : "
+ lokal.getFileName().toString().startsWith("olah-"));
Files.delete(lokal);
System.out.println("hapus manual : " + Files.deleteIfExists(sementara));
System.out.println("masih ada : " + Files.exists(sementara));
}
}Output yang Dihasilkan:
awalan cocok : true
akhiran cocok : true
berkas ada : true
isi utuh : true
lokal cocok : true
hapus manual : true
masih ada : falseAlur program tersebut menegaskan empat sifat penting:
- Baris 8 (
createTempFile("catatan-", ".txt")): prefix membantu manusia mengenali asal berkas saat memeriksa isi/tmp— kebiasaan yang sangat membantu saat debugging. - Baris 14-15 (
writeString+readString): berkas sementara adalah berkas biasa — bisa ditulis, dibaca, diperiksa atributnya, dan di-watch seperti chapter sebelumnya. - Baris 18-20 (
createTempFile(Path.of("."), ...)): berkas sementara tidak harus di/tmp; varian berdirektori menaruhnya di direktori kerja, tetapi keacakan namanya tetap dijaga. - Baris 22-23 (
deleteIfExists): pembersihan eksplisit segera setelah berkas selesai dipakai — pola terbaik yang tidak menunda tanggung jawab.
Menjaga Kebersihan dengan deleteOnExit dan Pembersihan Manual #
Dua strategi pembersihan tersedia. Yang otomatis: deleteOnExit() (atau File.deleteOnExit di API lama) memerintahkan JVM menghapus berkas saat program berakhir secara normal. Yang manual: memanggil Files.delete di akhir pemakaian — biasanya dalam blok finally atau setelah operasi sukses. Keduanya punya bidik masing-masing: deleteOnExit menyelamatkan program singkat dari lupa, sedangkan pembersihan manual wajib untuk aplikasi berumur panjang.
Program berikut membandingkan kedua gaya sekaligus memakai direktori sementara sebagai wadah kerja:
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class BersihSementara {
public static void main(String[] args) throws IOException {
// API lama java.io.File + deleteOnExit.
File warisan = File.createTempFile("laporan-", ".tmp");
warisan.deleteOnExit();
System.out.println("File lama : "
+ warisan.getName().startsWith("laporan-"));
// API modern: direktori sementara khusus, dibersihkan manual.
Path kerja = Files.createTempDirectory("olah-");
Path antara = Files.createTempFile(kerja, "langkah-", ".part");
System.out.println("di subfolder : "
+ antara.getParent().getFileName().toString().startsWith("olah-"));
Files.writeString(antara, "hasil antara");
System.out.println("isi : " + Files.readString(antara));
Files.delete(antara);
Files.delete(kerja);
System.out.println("dibersihkan : "
+ (Files.notExists(antara) && Files.notExists(kerja)));
}
}Output yang Dihasilkan:
File lama : true
di subfolder : true
isi : hasil antara
dibersihkan : trueDua gaya pembersihan pada program tersebut layak dibedah:
- Baris 9-10 (
File.createTempFile+deleteOnExit): API lama menghasilkanFile, bukanPath, dandeleteOnExit()mencatatnya dalam daftar internal JVM. Daftar itu dieksekusi hanya pada penutupan normal — program yang berhenti paksa,System.exitdi tengah exception berat, atau crash JVM meninggalkan berkasnya tetap di disk. - Baris 14-15 (
createTempDirectory): pabrik direktori sementara bekerja dengan keacakan nama yang sama; direktori kerja khusus mengelompokkan semua berkas antara satu proses sehingga pembersihan tinggal menghapus satu pohon. - Baris 22-23 (
deleteberurutan): berkas dulu baru direktorinya —deletemenolak direktori yang masih berisi, urutan ini wajib.Files.notExistskemudian memastikan keduanya benar-benar hilang.
Kita kini memegang kendali penuh atas keberadaan berkas. Pertanyaan berikutnya menyangkut siapa yang boleh menyentuhnya: hak akses. Chapter berikutnya membahas Files.isReadable, isWritable, isExecutable, serta permission POSIX yang mengatur hidup-mati akses pada Linux dan sistem UNIX lainnya.
Referensi #
- Oracle: Class Files createTempFile (Java SE 25 API)
- Oracle: Class File deleteOnExit (Java SE 25 API)
- dev.java: Java I/O
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
BerkasSementara.java
Unduh berkasimport java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class BerkasSementara {
public static void main(String[] args) throws IOException {
Path sementara = Files.createTempFile("catatan-", ".txt");
String nama = sementara.getFileName().toString();
System.out.println("awalan cocok : " + nama.startsWith("catatan-"));
System.out.println("akhiran cocok : " + nama.endsWith(".txt"));
System.out.println("berkas ada : " + Files.exists(sementara));
Files.writeString(sementara, "data sementara");
System.out.println("isi utuh : "
+ Files.readString(sementara).equals("data sementara"));
// Di direktori kerja sendiri: nama tetap dibuat acak.
Path lokal = Files.createTempFile(Path.of("."), "olah-", ".tmp");
System.out.println("lokal cocok : "
+ lokal.getFileName().toString().startsWith("olah-"));
Files.delete(lokal);
System.out.println("hapus manual : " + Files.deleteIfExists(sementara));
System.out.println("masih ada : " + Files.exists(sementara));
}
}
BersihSementara.java
Unduh berkasimport java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class BersihSementara {
public static void main(String[] args) throws IOException {
// API lama java.io.File + deleteOnExit.
File warisan = File.createTempFile("laporan-", ".tmp");
warisan.deleteOnExit();
System.out.println("File lama : "
+ warisan.getName().startsWith("laporan-"));
// API modern: direktori sementara khusus, dibersihkan manual.
Path kerja = Files.createTempDirectory("olah-");
Path antara = Files.createTempFile(kerja, "langkah-", ".part");
System.out.println("di subfolder : "
+ antara.getParent().getFileName().toString().startsWith("olah-"));
Files.writeString(antara, "hasil antara");
System.out.println("isi : " + Files.readString(antara));
Files.delete(antara);
Files.delete(kerja);
System.out.println("dibersihkan : "
+ (Files.notExists(antara) && Files.notExists(kerja)));
}
}