In Java, When I Call Outputstream.Close() Do I Always Need to Call Outputstream.Flush() Before

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

Close() always flushes so no need to call.

EDIT: This answer is based on common sense and all the outputstream I encountered. Who is going to implement a close() for a buffered stream without flushing buffer first? There is no harm to call flush right before close(). However, there are consequences if flush() is called excessively. It may defeat underneath buffering mechanism.

FileOutputStream: Does the close method calls also flush?

The method flush is used to "flush" bytes retained in a buffer. FileOutputStream doesn't use any buffer, so flush method is empty. Calling it or not doesn't change the result of your code.

With buffered writers the method close call explicitly flush.

So you need to call flush when you like to write the data before closing the stream and before the buffer is full (when the buffer is full the writer starts writing without waiting a flush call).

The source code of class FileOutputStream hasn't a custom version of method flush. So the flush method used is the version of its super class OutputStream. The code of flush in OutputStream is the following

public void flush() throws IOException {
}

As you see this is an empty method doing nothing, so calling it or not is the same.

Do we really need to call flush() just before close() today?

As the javadoc says, you don't need to flush yourself.
But, it's still good to do, considering your readers, and common sense.

Few experts know the javadoc by heart.
I wouldn't know for sure if the stream will be flushed or not without looking it up,
and I'm probably not alone.
Seeing the explicit flush() call makes this perfectly clear,
and therefore makes the code easier to read.

Furthermore, the method name close() implies nothing about flushing.
It's from the Closeable interface,
and naturally, it says nothing about flushing.
If you don't flush a buffered output stream before closing,
despite wanting to flush it,
you'll be relying on assumptions that may or may not be true.
It would weaken your implementation.

Any assumptions you make,
you should somehow pass on to future maintainers.
One way to do that is by leaving a comment:

// no need to flush() manually, close() will do it automatically

If you don't leave this comment,
future maintainers may have to lookup the javadoc too,
if like me they don't have it memorized.
But then, why would you write such comment when it's easier and better to just call it yourself now and be done with it.

In short, flushing first before closing is simply following good logic.
No need for assumptions and second guesses,
and no need to make your readers think.

Do i need to flush or close the OutputStream in my custom Spring Web MessageConverter

Never call close() method anywhere.

You should never call close() method as it will immediately disconnect the client socket and their will be no point executing request further on server as the client request is already processed. Also it will trimmed out all the configured post filters and interceptors execution that may results in various error condition.

Why should we not call close method on response stream/writer?

Response stream will be eventually closed by container itself at the end of request processing so you should not worry about calling it manually. Just write your custom converter as you want it to be.

Also you don't need to flush the content as being a buffered output stream, content is automatically being flushed when buffers runs out of the capacity.

Gson converter may have it mistakenly and request will still terminate as soon as json data is written to response stream. As you already know the consequences of using them. If this is really going to create any problem in your case then you can think of MappingJackson2HttpMessageConverter as alternative, it doesn't close the output stream after writing json string into it.

But if you writing a new converter, then it will be a better idea not to close the streams anywhere in the code.

Using flush() before close()

Developer get into a habit of calling flush() after writing something which must be sent.

IMHO Using flush() then close() is common when there has just been a write e.g.

// write a message
out.write(buffer, 0, size);
out.flush();

// finished
out.close();

As you can see the flush() is redundant, but means you are following a pattern.

does close a socket will also close/flush the input/output stream

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

says that yes! It will be flushed if you close it manually

Is flush() call necessary when using try-with-resources

Closeable and AutoCloseable are general-purpose interfaces that do not know anything about flushing. So you can't find any information about it in their documentation - except some words about releasing resources.

A Writer on the other hand is a more specific-purpose abstract class that now knows something about flushing. Some excerpt of the documentation for the method Writer.close():

Closes the stream, flushing it first.

So - yes - when using a writer, a close will always also flush. This basically means that you have to consult the documentation of the concrete classes that you are using when trying to find out what closing really does.

if outputStream.close() fails, the stream will still be closed and the system resources will still be released?

Try-with-resouces ensures close() is always called, that's it. It doesn't do anything else with the resource if the close() method throws an exception, because there is nothing else that can be done.

If close() throws exception, you should consider the resource to have been released, but it may have left the resource in an incomplete state. E.g. closing an OutputStream may flush the final buffer, and the writing of that data may fail, leaving the resource (e.g. file) missing the last chunk of data.



Related Topics



Leave a reply



Submit