Anda dapat menutup aliran paling luar, bahkan Anda tidak perlu mempertahankan semua aliran yang dibungkus dan Anda dapat menggunakan Java 7 coba-dengan-sumber daya.
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new GZIPOutputStream(new FileOutputStream(createdFile)))) {
// write to the buffered writer
}
Jika Anda berlangganan YAGNI, atau Anda -tidak akan membutuhkannya, Anda seharusnya hanya menambahkan kode yang benar-benar Anda butuhkan. Anda seharusnya tidak menambahkan kode yang Anda bayangkan mungkin Anda butuhkan tetapi pada kenyataannya tidak melakukan sesuatu yang bermanfaat.
Ambil contoh ini dan bayangkan apa yang mungkin salah jika Anda tidak melakukan ini dan apa dampaknya?
try (
OutputStream outputStream = new FileOutputStream(createdFile);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
OutputStreamWriter osw = new OutputStreamWriter(gzipOutputStream);
BufferedWriter bw = new BufferedWriter(osw)
) {
// ...
}
Mari kita mulai dengan FileOutputStream yang memanggil open
untuk melakukan semua pekerjaan nyata.
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private native void open(String name, boolean append)
throws FileNotFoundException;
Jika file tidak ditemukan, tidak ada sumber daya yang mendasarinya untuk ditutup, jadi menutupnya tidak akan membuat perbedaan. Jika file ada, itu harus membuang FileNotFoundException. Jadi tidak ada yang bisa diperoleh dengan mencoba menutup sumber daya dari garis ini saja.
Alasan Anda perlu menutup file adalah ketika file dibuka dengan sukses, tetapi Anda kemudian mendapatkan kesalahan.
Mari kita lihat aliran selanjutnya GZIPOutputStream
Ada kode yang bisa melempar pengecualian
private void writeHeader() throws IOException {
out.write(new byte[] {
(byte) GZIP_MAGIC, // Magic number (short)
(byte)(GZIP_MAGIC >> 8), // Magic number (short)
Deflater.DEFLATED, // Compression method (CM)
0, // Flags (FLG)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Extra flags (XFLG)
0 // Operating system (OS)
});
}
Ini menulis header file. Sekarang akan sangat tidak biasa bagi Anda untuk dapat membuka file untuk menulis tetapi tidak dapat menulis bahkan 8 byte untuk itu, tetapi mari kita bayangkan ini bisa terjadi dan kami tidak menutup file setelahnya. Apa yang terjadi pada file jika tidak ditutup?
Anda tidak mendapatkan tulisan yang tidak disiram, mereka dibuang dan dalam hal ini, tidak ada byte yang berhasil ditulis ke aliran yang tidak buffer pada saat ini. Tetapi file yang tidak ditutup tidak hidup selamanya, sebaliknya FileOutputStream memiliki
protected void finalize() throws IOException {
if (fd != null) {
if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
flush();
} else {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
}
Jika Anda tidak menutup file sama sekali, file tetap akan ditutup, tidak segera (dan seperti saya katakan, data yang tersisa di buffer akan hilang dengan cara ini, tetapi tidak ada pada saat ini)
Apa konsekuensi dari tidak segera menutup file? Dalam kondisi normal, Anda berpotensi kehilangan beberapa data, dan Anda berpotensi kehabisan file deskriptor. Tetapi jika Anda memiliki sistem di mana Anda dapat membuat file tetapi Anda tidak dapat menulis apa pun kepada mereka, Anda memiliki masalah lebih besar. yaitu sulit membayangkan mengapa Anda berulang kali mencoba membuat file ini meskipun Anda gagal.
Baik OutputStreamWriter dan BufferedWriter tidak melempar IOException ke konstruktor mereka, jadi tidak jelas masalah apa yang akan mereka sebabkan. Dalam kasus BufferedWriter, Anda bisa mendapatkan OutOfMemoryError. Dalam hal ini akan segera memicu GC, yang seperti telah kita lihat akan menutup file.