Tuesday, May 13, 2014

Close() But No Cigar

The ByteArrayInputStream.close(), it does nothing! And it thus allows reading bytes from the ByteArrayInputStream object after calling close() on it.

Of course someone like me has to make a mistake, closing the ByteArrayInputStream on creation. I did, by leaving a "try-with-resources" in place during refactoring, returning the 'implicitly' closed stream.

Result: 1-2 hours extra debugging, thinking that my code, using XMLStreamReader, tested with ByteArrayInputStream and string literals, had some error causing it to skip prematurely all the way to the end.

An easy fix is to use your own subclass and override close(). Something like this:
/**
* Otherwise, java input stream might return data even when closed. 
* {@link super#close()} does nothing. 
*/
@Override
public void close() throws IOException {
    this.pos = count + 1; // distinct from the 'real' EOF; might be useful.
    super.close(); // does nothing in super, but whatever. 
}

And why doesn't the standard library do this? There seems to be no performance penalty. Well, maybe there is, maybe it's kind of wrong to return EOF (-1) here, maybe it should throw an exception. But is returning bytes after closing better?

No comments:

Post a Comment