10
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
    }
}

Does closing zos automatically closes bos and fos too, or do I need to close them manually?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
sp00m
  • 47,968
  • 31
  • 142
  • 252
  • 2
    You should also be careful to *always* close the outermost stream; otherwise you may experience data loss due to unflushed buffers in wrapper streams which got their wrapped stream closed under their nose. – Marko Topolnik Aug 05 '13 at 09:39

4 Answers4

8

Yes, it does. Its Javadoc says:

Closes the ZIP output stream as well as the stream being filtered.

Also, the Javadoc for BufferedOutputStream says:

Closes this output stream and releases any system resources associated with the stream.

The close method of FilterOutputStream calls its flush method, and then calls the close method of its underlying output stream.

So when you close your ZipOutputStream, it will close your BufferedOutputStream, which will in turn close your FileOutputStream.

mthmulders
  • 9,483
  • 4
  • 37
  • 54
3

Yes.

ZipOutputStream.close() method is specified by Closeable.close() which:

Closes this stream and releases any system resources associated with it.

The same applies to BufferedOutputStream.close(), a method inherited from FilterOutputStream.

2

Closing the wrapper stream automatically closes the inner stream.

So, in your case you only need to close ZipOutputStream. Closing a stream twice does not throw an exception hence closing an inner stream again (although unnecessary) works as well.

Here's what happens when you instantiate a ZipOutputStream

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

Here's the implementation of ZipOutputStream.close()

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

Similarly, BufferedOutputStream automatically closes the FileOutputStream through its inherited FilterOutputStream#close() which has been implemented as:

public void close() throws IOException {
    try {
      flush();
    } catch (IOException ignored) {
    }
    out.close(); // FileOutputStream being closed
}
Ravi K Thapliyal
  • 51,095
  • 9
  • 76
  • 89
0

Yes it does. but strangely when i was running the fortify scan with find bug enabled it catches all these kind of wrapped and unclosed streams as high priority items to be fixed. Not sure why they do so

Shravan Ramamurthy
  • 3,896
  • 5
  • 30
  • 44