21
InputStream in = SomeClass.getInputStream(...);
BufferedInputStream bis = new BufferedInputStream(in);

try {
    // read data from bis
} finally {
    bis.close();
    in.close();    
}

The javadoc for BufferedInputStream.close() doesn't mention whether or not the underlying stream is closed:

Closes this input stream and releases any system resources associated with the stream. Once the stream has been closed, further read(), available(), reset(), or skip() invocations will throw an IOException. Closing a previously closed stream has no effect.

Is the explicit call to in.close() necessary, or should it be closed by the call to bis.close()?

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
  • 1
    Short answer: Yes. Long answer: Yeeeeesssss. Seriously, look at http://www.docjar.com/html/api/java/io/BufferedInputStream.java.html#472 – Marco13 Jun 23 '14 at 09:57

5 Answers5

29

From the source code of BufferedInputStream :

public void close() throws IOException {
    byte[] buffer;
    while ( (buffer = buf) != null) {
        if (bufUpdater.compareAndSet(this, buffer, null)) {
            InputStream input = in;
            in = null;
            if (input != null)
                input.close();
            return;
        }
        // Else retry in case a new buf was CASed in fill()
    }
}

So the answer would be : YES

Dangling Piyush
  • 3,658
  • 8
  • 37
  • 52
omu_negru
  • 4,642
  • 4
  • 27
  • 38
9

BufferedInputStream doesn't hold any system resources itself; it simply wraps around an InputStream which holds those resources. Therefore the BufferedInputStream forwards the close operation onto the wrapped InputStream which will then release its resources.

drrob
  • 632
  • 7
  • 16
ConMan
  • 1,642
  • 1
  • 14
  • 22
7

When you close a BufferedInputStream, the underlying InputStream is indeed also closed. :)

rhobincu
  • 906
  • 1
  • 7
  • 22
  • Can you provide a reference? – Graham Borland Jun 23 '14 at 09:55
  • @GrahamBorland you can simply look the source code of Java – Sergiy Medvynskyy Jun 23 '14 at 09:56
  • Also, that would be my reading of "releases any system resources associated with the stream". But yeah, they could be more explicit. – Thilo Jun 23 '14 at 09:57
  • @GrahamBorland There are dozens of similar questions on stackoverflow already. I'll link a few: http://stackoverflow.com/questions/12199142/closing-bufferedreader-and-inputstreamreader http://stackoverflow.com/questions/1388602/do-i-need-to-close-both-filereader-and-bufferedreader http://stackoverflow.com/questions/11263926/closing-inputstreams-in-java – rhobincu Jun 23 '14 at 09:59
  • @rhobincu Thanks, I couldn't find any when I searched. Those all refer to `Reader`s rather than `InputStream`s but they're close enough I guess. – Graham Borland Jun 23 '14 at 10:01
3

Yes. The underlying stream will be closed.

Nova Entropy
  • 5,727
  • 1
  • 19
  • 32
2

Here is the Java implementation

/**
 * Closes this input stream and releases any system resources
 * associated with the stream.
 * Once the stream has been closed, further read(), available(), reset(),
 * or skip() invocations will throw an IOException.
 * Closing a previously closed stream has no effect.
 *
 * @exception  IOException  if an I/O error occurs.
 */
public void close() throws IOException {
    byte[] buffer;
    while ( (buffer = buf) != null) {
        if (bufUpdater.compareAndSet(this, buffer, null)) {
            InputStream input = in;
            in = null;
            if (input != null)
                input.close();
            return;
        }
        // Else retry in case a new buf was CASed in fill()
    }
}

So, the stream will be closed

Sergiy Medvynskyy
  • 11,160
  • 1
  • 32
  • 48