56

Short question,

I saw in some old code where a ByteArrayInputStream was created like:

new BufferedReader(new InputStreamReader(new ByteArrayInputStream(somebytes)));

And then the BufferedReader is used to read out somebytes line by line.
All working fine, but I noticed that the BufferedReader is never closed.
This is all working in a long running websphere application, the somebytes are not terrible big (200k most), it is only invoked a few times a week and we're not experiencing any apparent memory leaks. So I expect that all the objects are successfully garbage collected.

I always (once) learned that input/output streams need to be closed, in a finally statement. Are ByteStreams the exception to this rule?

kind regards Jeroen.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
dr jerry
  • 9,768
  • 24
  • 79
  • 122
  • 1
    Thank you all for your answers and hints! As a commenter below pointed out it was a matter of RTFM or "Have you googled it?" as the latter did almost immediately reveal the answer. However to my knowledge it was unasked at stackoverflow till now, and the bonus was the hints aside – dr jerry Feb 26 '11 at 08:39

4 Answers4

58

You don't have to close ByteArrayInputStream, the moment it is not referenced by any variable, garbage collector will release the stream and somebytes (of course assuming they aren't referenced somewhere else).

However it is always a good practice to close every stream, in fact, maybe the implementation creating the stream will change in the future and instead of raw bytes you'll be reading file? Also static code analyzing tools like PMD or FindBugs (see comments) will most likely complain.

If you are bored with closing the stream and being forced to handle impossible IOException, you might use IOUtils:

IOUtils.closeQuietly(stream);
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • I think there's probably a few more impossible `IOException`s in there, given that the code is not actually dealing with any I/O at all! – Tom Hawtin - tackline Feb 25 '11 at 14:35
  • 9
    findbugs is smart enough not to report BAIS/BAOS not being closed. – MeBigFatGuy Feb 25 '11 at 14:53
  • @Tom Hawtin - tacklin: the beauty of having checked exceptions :-( – Tomasz Nurkiewicz Feb 25 '11 at 15:06
  • Actually, you could get an EOF exception if used in certain ways, couldn't you? – Tom Hawtin - tackline Feb 25 '11 at 15:14
  • So if the Stream/File/Reader/WhateverIoObject goes out of scope it's automatically closed? – poitroae Aug 08 '13 at 21:28
  • If `ByteArrayInputStream.close()` will never throw an `IOException`, there would be no good reason for `ByteArrayInputStream.close()` to declare that is `throws IOException`. Although `InputStream` declares it `throws`, an overriding method may throw a sub set of the exceptions of the declared exceptions of the base class or interface. So either the Java implementers want to reserve the right for `ByteArrayInputStream.close()` to throw an exception, or they made a mistake. – Raedwald Nov 01 '13 at 15:17
  • We should add that there is try-with-resource since Java 7 which fixes most cases where closeQuietly-utils came in handy. – Tim Büthe Oct 22 '15 at 07:29
  • As @TomaszNurkiewicz mentioned it's always good to close the opened stream. – KulDeep Sep 07 '17 at 07:41
  • Closing a {@code ByteArrayInputStream} has no effect. The methods in this class can be called after the stream has been closed without generating an {@code IOException}. From ByteArrayInputStream.java – Adrian Madaras Sep 03 '19 at 10:52
  • 1
    IOUtils.closeQuietly(stream) is Deprecated – Chhorn Elit Aug 19 '20 at 06:56
13

It is always good practice to close your readers. However not closing a ByteArrayInputStream does not have as heavy of a potential negative effect because you are not accessing a file, just a byte array in memory.

jzd
  • 23,473
  • 9
  • 54
  • 76
  • 6
    The documentation for ByteArrayInputStream will confirm that close() does nothing. But it's a good idea to stay in the practice of calling close on streams. You might later refactor to make a function accept other kinds of streams. – Nick Feb 25 '11 at 14:18
3

As @TomaszNurkiewicz mentioned it's always good to close the opened stream. Another good way to let it do the try block itself. Use try with resource like.......

try ( InputStream inputStream = new ByteArrayInputStream(bytes); Workbook workBook = new XSSFWorkbook(inputStream)) { 

here Workbook and InputStream both implements Closeable Interface so once try block completes ( normally or abruptly), stream will be closed for sure.

KulDeep
  • 441
  • 4
  • 8
1

Resources need to be closed in a finally (or equivalent). But where you just have some bytes, no it doesn't matter. Although when writing, be careful to flush in the happy case.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305