2013-08-05 21 views
5
OutputStream fos; 
OutputStream bos; 
OutputStream zos; 
try { 
    fos = new FileOutputStream(anyFile); 
    bos = new BufferedOutputStream(fos); 
    zos = new ZipOutputStream(bos); 
} finally { 
    if (zos != null) { 
     zos.close(); // + exception handling 
    } 
} 

閉じるzosは自動的にbosfosを閉じますか、または手動で閉じる必要がありますか?ネストしたストリームを閉じると、その親ストリームも閉じますか?

+1

また、最外ストリームを常に*閉じる*に注意する必要があります。そうしないと、ラップされたストリームが鼻の下で閉じられたラッパーストリーム内のバッファがフラッシュされていないためにデータが失われる可能性があります。 –

答えて

5

はい、あります。そのJavadocはこう言います:

フィルタリングされるストリームと同様に、ZIP出力ストリームを閉じます。

また、Javadoc for BufferedOutputStreamは言う:

この出力ストリームを解放ストリームに関連するすべてのシステムリソースを閉じます。

FilterOutputStreamclose方法は、そのflushメソッドを呼び出し、その基本となる出力ストリームのclose方法を呼び出します。あなたはZipOutputStreamを閉じたとき

だから、それは順番にあなたのFileOutputStreamを閉じますあなたのBufferedOutputStream、閉じます。

2

ラッパーストリームを閉じると、自動的に内部ストリームが閉じられます。

あなたの場合、ZipOutputStreamを閉じるだけで済みます。ストリームを2回閉じると例外がスローされないため、内部ストリームをもう一度閉じます(不要な場合もあります)。

ここでは、ZipOutputStream

public ZipOutputStream(OutputStream out) { 
    this.out = out; // BufferedOutputStream reference saved 
} 

をインスタンス化したときに何が起こるかだ。ここZipOutputStream.close()

public void close() throws IOException { 
    try { 
     flush(); 
    } catch (IOException ignored) { 
    } 
    out.close(); // BufferedOutputStream being closed 
} 

の実装は同様に、BufferedOutputStreamが自動的として実装されてきたその継承FilterOutputStream#close()を通じてFileOutputStreamを閉じています:

public void close() throws IOException { 
    try { 
     flush(); 
    } catch (IOException ignored) { 
    } 
    out.close(); // FileOutputStream being closed 
} 
0

はい。不思議なことに、バグを発見して要塞スキャンを実行していたとき、これらの種類のラップされたストリームと閉じられていないストリームをすべて優先順位の高い項目としてキャッチして修正しました。なぜそうするのかわからない

関連する問題