2

Is available() reliable for use in socket programming in Java?

I just care that it tells me when there are bytes available for reading so that when I call read methods they don't block.

BufferedInputStream.available() relies on InputStream.available().

The documentation for InputStream.available() says this:

Note that while some implementations of InputStream will return the total number of bytes in the stream, many will not. It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream. http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#available()

I don't care if it gives the correct number of bytes or not, just that it doesn't give me 0 when there are bytes available for reading. I want to know if BufferedInputStream.available() always works for this purpose on Windows and Linux.

Also, I'm not sure what the documentation means by "implementations". What does that refer to? To subclasses of InputStream? To Java on different operating systems? To different JVMs?

Has anybody used available() on Windows or Linux or other system and it didn't work?

Franz Kafka
  • 10,623
  • 20
  • 93
  • 149
mudgen
  • 7,213
  • 11
  • 46
  • 46
  • Never use `available`. Ever. If you want to be notified when `byte`s are available for `read`ing, take a look at [non-blocking IO](http://www.developer.com/java/article.php/3837316/Non-Blocking-IO-Made-Possible-in-Java.htm). – Jeffrey Aug 23 '12 at 01:25
  • What is the reason for never using available? If we should never use it then why does it exist? – mudgen Aug 23 '12 at 01:27
  • If you're certain you know how `available` will work with your specific `InputStream`, then you may use it. However, most uses of `InputStream` boil down to `FileInputStream` or `Socket.getInputStream()`, neither of which are guaranteed to return correct `available` values. – Jeffrey Aug 23 '12 at 01:31
  • @Jeffery: I don't care if available() returns a correct value or not. I just care that it doesn't return 0 when bytes are available to be read. Are you saying this might not work? Thanks for your help! – mudgen Aug 23 '12 at 01:36
  • @Jeffrey - "Never use `available`" seems a little extreme. While the return value is not guaranteed "correct" in the sense of indicating how much input will eventually be available, it is a valid lower bound on how much input can be read without blocking. On the other hand, your suggestion to use the nio package is well taken. – Ted Hopp Aug 23 '12 at 01:36
  • 1
    @TedHopp @mudge The problem with `available` is that it can always return `0` and never be wrong. It's always better not to rely on `available` as an indicator for anything. – Jeffrey Aug 23 '12 at 01:42
  • I found out that the underlying InputStream of Socket.getInputStream() is java.net.SocketInputStream, and the documentation for that says, "Returns the number of bytes that can be read without blocking.". Seems like it should work. Documentation here: http://javasourcecode.org/html/open-source/jdk/jdk-6u23/java/net/SocketInputStream.html – mudgen Aug 23 '12 at 01:42
  • @Jeffery: If there are bytes available for reading and available() returns 0, then wouldn't it be wrong? Are you saying that it is never wrong when always returning 0 and no data is ever sent over the network to be read? – mudgen Aug 23 '12 at 01:45
  • 1
    @mudge No. Read the specification for the method: `some implementations of InputStream will return the total number of bytes in the stream, many will not`. This means that the `available` method can more or less return any value it wants. – Jeffrey Aug 23 '12 at 01:47
  • But the documentation of the implementation I am using (java.net.SocketInputStream) says "Returns the number of bytes that can be read without blocking." But I get your point, maybe this doesn't always work reliably. – mudgen Aug 23 '12 at 02:25
  • possible duplicate of [When is InputStream.available() useful?](http://stackoverflow.com/questions/12082709/when-is-inputstream-available-useful) – user207421 Aug 23 '12 at 03:18
  • @TedHopp It is a valid *upper* bound on how much data can be read without blocking. Hence the caveats about what the subsequent read may do, quoted in your answer, and it is also why zero is always a legitimate return value. – user207421 Aug 23 '12 at 03:26

2 Answers2

2

The same doc that you link to in your question says:

A single read or skip of this many bytes will not block, but may read or skip fewer bytes.

So I'd say that it's "safe" in the sense that I/O will not block when it does not return 0. On the other hand, there is no guarantee that it will return non-zero when there are, in fact, bytes to be read.

Note that InputStream is an abstract class, so any InputStream object you have will of necessity be a subclass. That's what the docs mean by an "implementation". Any concrete subclass will have implemented all abstract methods.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • 1
    @mudge if you really want non-blocking I/O, try looking into [NIO](http://rox-xmlrpc.sourceforge.net/niotut/index.html). – obataku Aug 23 '12 at 02:29
1

It is definitely not reliable when wrapped around an SSLSocket, as I have already told you in your other thread. It always returns zero.

Community
  • 1
  • 1
user207421
  • 305,947
  • 44
  • 307
  • 483