Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you force a flush on an OutputStream object without closing it?

My question lies on the following assumptions which I hope are true, because I believe these as I read them while Googling my problems:

  1. Closing a Socket's OutputStream closes the socket too
  2. The flush() method of OutputStream does nothing

So I basically need to anyhow flush the data out of my OutputStream object for my app to work.

If you're interested in details then please see the following two links :

. Weird behavior : sending image from Android phone to Java server (code working)

This issue was resolved by closing the OutputStream. Doing that flushed all the data to the other end of the socket and made my app working further but this fix soon gave rise to problem number 2 - the corresponding socket also gets closed :

. SocketException - 'Socket is closed' even when isConnected() returns true

like image 356
GrowinMan Avatar asked Apr 15 '12 22:04

GrowinMan


3 Answers

You can call the flush method of OutputStream instead of close. The concrete classes inheriting from OutputStream will override flush() to do something other than nothing (writing the data to a file or sending it over the network).

like image 108
smichak Avatar answered Sep 18 '22 20:09

smichak


The flush() method of OutputStream does nothing.

This is incorrect.

It is true that the base implementation of flush() provided by the OutputStream class does nothing. However, your app will be calling the version of that method that is provided by actual stream class that you are using. If the stream class doesn't have direct write semantics, it will override flush() to do what is required.

In short, if a flush is required (and it is required for a Socket output stream), then calling flush() will do the right thing. (If some internet source tells you otherwise it is either wrong or you are misinterpreting it.)


FYI, the reason that the base OutputStream implements flush() as a no-op is that:

  • some output stream classes don't need to do anything when flushed; e.g ByteArrayOutputStream, and
  • for the stream classes where flush() is not a no-op, there is no way to implement the operation at the base class level.

They could (in theory) have made designed the stream APIs so that OutputStream was an abstract class (and flush() an abstract method) or an interface. However this API was effectively frozen prior to Java 1.0, and at that time there wasn't enough experience with practical Java programming to realize that the API design was suboptimal.

like image 27
Stephen C Avatar answered Sep 18 '22 20:09

Stephen C


Closing a Socket's OutputStream closes the socket too

True.

The flush() method of OutputStream does nothing

False. There are overrides. See the Javadoc for FilterOutputStream.flush(), BufferedOutputStream.flush(), ObjectOutputStream.flush(), to name a few.

So your initial problem is non-existent, so you have no need for the 'solution' that causes problem #2.

like image 20
user207421 Avatar answered Sep 17 '22 20:09

user207421