What does InputStream.available() do in Java?
Asked Answered
N

2

67

What does InputStream.available() do in Java? I read the documentation, but I still cannot make it out.

The doc says:

Returns the number of bytes that can be read (or skipped over) from this input stream without blocking by the next caller of a method for this input stream. The next caller might be the same thread or or another thread.

The available method for class InputStream always returns 0.

What do they mean by blocking? Does it just mean a synchronized call?

And most of all, what is the purpose of the available() method?

Nostomania answered 12/9, 2010 at 15:27 Comment(1)
There are very few genuinely useful uses of available(). One of them is for reading from System in.Tabor
A
37

Blocking doesn't relate to threading or synchronisation here. Instead it relates to blocking IO (see this for more info). If you issue a request to read, and the channel has none available, a blocking call will wait (or block) until data is available (or the channel is closed, throws an exception etc.)

So why use available() ? So you can determine how many bytes to read, or determine whether you're going to block.

Note that Java has non-blocking IO capabilities as well. See here for more details

Abdicate answered 12/9, 2010 at 15:34 Comment(2)
I stumbled upon this question and am now wondering, can I use available() to solve my own problem, without resorting to NIO. My question: #3867542Thenceforth
This answer is not correct. A blocking call will block while there is no data available. If you ask for four and there are three, you get three.Tabor
P
55

In InputStreams, read() calls are said to be "blocking" method calls. That means that if no data is available at the time of the method call, the method will wait for data to be made available.

The available() method tells you how many bytes can be read until the read() call will block the execution flow of your program. On most of the input streams, all call to read() are blocking, that's why available returns 0 by default.

However, on some streams (such as BufferedInputStream, that have an internal buffer), some bytes are read and kept in memory, so you can read them without blocking the program flow. In this case, the available() method tells you how many bytes are kept in the buffer.

Permutation answered 12/9, 2010 at 15:30 Comment(8)
BufferedInputStream.available() tells you how many bytes can be read without blocking. This is the sum of the number of bytes already in the buffer and the avaiable() result of the nested input stream. Note also that available() always returns zero for an SSL socket.Tabor
What I didn't quite understand is what is the use of knowing this. I really, can't see why should I care, i.e. I can't see where and when in mu app I could find it some use. Of course, it's pretty obvious, that I am being ignorant, but that's is for my lack of experience.Nostomania
As I said above, there are very few useful uses. You have to know you're dealing with a stream that will deliver a non-zero answer and then you have to have a use for the result.Tabor
Can you please explain what do you mean by if no data is available at the time of the method call, the method will wait for data to be made available? Say I have a file with no content. If I invoke that in the FileInputStream, will it forever wait for data to come from the file? Does that mean that whatever followed the invocation of the stream in the original code will be put on hold indefinitely?Coburn
@Cupidvogel: No, for a file with no content, the stream will return -1 immediately to indicate that there's no data. If you have a network-based stream, however, where the other end of the connection is holding it open but not sending any data, then that would indeed block forever.Flaw
Thanks. What is meant by blocking execution flow? And also what is meant by On most of the input streams, all call to read() are blocking, that's why available returns 0 by default.?Coburn
"Blocking execution flow" means that the function will not return until the next byte is fetched from the input source (eg disk, internet). You should consider that most implementations of input streams fetch one byte at a time. If this is unacceptable (and it is), wrap it in a BufferedInputStream.Geese
On all input streams, reads are blocking, and this is not why available() returns zero by default. There are many cases of streams that can return non-zero, not just the buffered ones that know locally: socket input streams, file input streams, HttpURLConnection input streams, ...Tabor
A
37

Blocking doesn't relate to threading or synchronisation here. Instead it relates to blocking IO (see this for more info). If you issue a request to read, and the channel has none available, a blocking call will wait (or block) until data is available (or the channel is closed, throws an exception etc.)

So why use available() ? So you can determine how many bytes to read, or determine whether you're going to block.

Note that Java has non-blocking IO capabilities as well. See here for more details

Abdicate answered 12/9, 2010 at 15:34 Comment(2)
I stumbled upon this question and am now wondering, can I use available() to solve my own problem, without resorting to NIO. My question: #3867542Thenceforth
This answer is not correct. A blocking call will block while there is no data available. If you ask for four and there are three, you get three.Tabor

© 2022 - 2024 — McMap. All rights reserved.