2013-08-05 41 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

是的。但奇怪的是,当我运行带有查找错误的强化扫描时,它捕获所有这些封装和未封闭的流作为要修复的高优先级项目。不知道他们为什么这样做