In Java, when I call OutputStream.close() do I always need to call OutputStream.flush() before?

Whilst close should call flush, it’s a bit more complicated than that…

Firstly, decorators (such as BufferedOutputStream) are common in Java. Construction of the decorator may fail, so you need to close the “raw” stream in a finally block whose try includes the decorator. In the case of an exception, you don’t usually need to close the decorator (except, for instance, for badly implemented compression decorators). You do typically need to flush the decorator in the non-exception case. Therefore:

final RawOutputStream rawOut = new RawOutputStream(rawThing);
try {
    final DecoratedOutputStream out = new DecoratedOutputStream(rawOut);
    // ... stuff with out within ...
    out.flush();
} finally {
    rawOut.close();
}

To top it, decorator close methods are often implemented incorrectly. That includes some in java.io until recently.

Of course, you probably want to use the Execute Around idiom to keep in DRY(ish).

Edit: Since Java 8 you can use try-with-resource statements that should handle everything nicely and concisely. The code will call close on each resource even if unnecessary.

try (
    RawOutputStream rawOut = new RawOutputStream(rawThing);
    DecoratedOutputStream out = new DecoratedOutputStream(rawOut)
) {
    // ... stuff with out within ...
}

Leave a Comment