2

When is InputStream.available() or BufferedInputStream.available() useful in socket programming in Java?

initramfs
  • 8,275
  • 2
  • 36
  • 58
mudgen
  • 7,213
  • 11
  • 46
  • 46
  • 2
    What happens if a blocking `read` method is called when there is no input available? What does the documentation for `available` say? -1 because no prior research is shown and no context is given (e.g. include something from the documentation or experience or *current problem* of interest to further refine the question). Also note that InputStream is *abstract*. –  Aug 22 '12 at 23:22
  • Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream. The next invocation might be the same thread or another thread. http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#available() – kosa Aug 22 '12 at 23:22
  • 1
    Any specific wording you couldn't get from documentation? – kosa Aug 22 '12 at 23:23
  • I mean what is an example of someone using it? – mudgen Aug 22 '12 at 23:57

1 Answers1

4

My take is that method is not useful unless you know how good the "estimate" is. And in the case of a stream connected to a socket, the estimate cannot be reliable in all cases.

The problem is that the method's return value does not distinguish between the cases where you have reached the end of stream on the socket, and where there are no characters currently available on the socket but more might be delivered. Both could return zero ... according to the javadoc.

This uncertainty renders the method pretty much useless.

  • In the socket case (and similar ones), the available() method doesn't really tell you whether to read or not if the result is zero. And if you make the wrong choice, you will either block when you don't mean to, or never discover that the socket has actually been closed. Either of those could be bad.

  • In other cases (like reading from a local file), there are other ways of finding whether the read is likely to block. Besides, the read is unlikely to block for long anyway, so there's usually not a great deal of point in avoiding blocking.

  • Finally, in some cases I think that you could get a non-zero response and have the read call block anyway. (I'm thinking of files on remote mounted file systems ... and the possibility of the remote server freezing when you try to read.)

The bottom line is that available() is documented as returning an estimate. The javadoc provides no guarantees of how reliable that estimate will be under all possible circumstances, and indeed in some circumstances the estimate cannot be accurate because that would require knowing what a remote server is going to do.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • "A single read or skip of this many bytes will not block, but may read or skip fewer bytes." <-- This for what I have used it for in the past. So, useless? Not for that. (Although some implementors *only* return 0 so ..) –  Aug 22 '12 at 23:37
  • @pst: I guess the point is you can't really rely on any given implementation giving you back anything useful. In your program, how would it handle an InputStream that always returns 0? Would you never read from it? – Mark Peters Aug 22 '12 at 23:39
  • @MarkPeters I would be aware of the implementation I was dealing with. As much fun as it's nice to believe an interface or abstract class can capture everything across all different sources/architectures .. honestly though for "sockets" I'd use NIO (or better, a wrapper for it). –  Aug 22 '12 at 23:39
  • @pst: That's kind of a false dilemma. InputStream *does* work across all environments, if you don't rely on things that the specification calls out as implementation-specific. I agree with you...if non-blocking I/O is what you're going for, use NIO. – Mark Peters Aug 22 '12 at 23:42
  • Just use BufferedInputStream.available(). It implements available so it does not return 0 everytime. – mudgen Aug 22 '12 at 23:52
  • 2
    @mudge Only if the underlying stream supports it. If it is say an SSLSocket it can still return zero. – user207421 Aug 23 '12 at 00:02