2013-08-05 82 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說:

關閉此輸出流並釋放與該流相關的所有系統資源。

close方法FilterOutputStream調用它的flush方法,然後調用其底層輸出流的close方法。

所以,當你閉上你的ZipOutputStream,它會關閉BufferedOutputStream,這將反過來關閉FileOutputStream

2

關閉包裝流會自動關閉內部流。

因此,在你的情況下,你只需要關閉ZipOutputStream。兩次關閉流不會拋出異常,因此再次關閉內部流(儘管不必要)也可以。

這裏發生了什麼,當你實例化一個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自動關閉已實現爲FileOutputStream通過其繼承FilterOutputStream#close()

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

是的。但奇怪的是,當我運行帶有查找錯誤的強化掃描時,它捕獲所有這些封裝和未封閉的流作爲要修復的高優先級項目。不知道他們爲什麼這樣做