The (Oracle's) javadoc of the InputStream.available() method says the following:
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. A single read or skip of this many bytes will not block, but may read or skip fewer bytes...
So the thing is that from a conceptual point of view, I would say that it makes sense that this method does not block. Otherwise, the purpose of "not blocking" in the next call to read() does not make much sense, because we could potentially block in available() itself.
The thing is that at my company we recently found several Android bluetooth implementations that block on the available() method, and we don't know if that's a bug we should report to vendors or just that available() can block.
Related
From the document, the function of the "available" method is:
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.
So, how long does it take for this method to return a result. If I have a file with 10000 words, and I want to go through each word by checking like this:
while (steam.available() > 0) {
steam.read(); // suppose that this read a word
}
So after each reading the first word, is the method going to go through the next 9999 words? And, after the second word, do it check the next 9998 words?
From the document, it say that the method "estimate the number of bytes", then how does it do that?
As it states, the purpose is to tell you how many bytes you can read without the read call blocking. This is mostly useful for network connections, where data is filling the buffer and you might want to process as much of that data without the read call blocking, waiting for more data.
It's not commonly used and doesn't tell you anything about how much is GOING to be available over all. For example, iv seen it used to test the length of a message, which is of course wrong, because only a part of the message may have been received at that point.
You are best to just read the whole stream until EOF is reached. available() will only be of use if you want to process as much data as you can without blocking. it says "estimate" because more data could be coming in all the time and you may have been able to read more bytes than available() returned at the exact moment you called it.
In practice, you need all the data from a stream, or you stop when you reach a certain value. But this is a separate issue to how quickly it streams in from where ever it's coming from. Wether it blocks or not - you will neither know nor care. :)
I'm using a Scanner for my socket connection in a Client/Server program.
I want Scanner.next() to block so the Server thread can wait for something to read.
However, it sometimes gives me:
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at cscie55.hw4.Server.serviceClient(Server.java:146)
at cscie55.hw4.Server.main(Server.java:106)
The java documentation says that next() "sometimes" blocks, and it doesn't say whether nextLine() blocks.
Some code online wraps it in an if that tests for null, but I read that it never returns null. What should I do to get blocking IO working properly in my socket?
Specifically,
When does Scanner.nextLine() block rather than throw NoSuchElementException?
The Scanner class will block whenever the InputStream used to construct it would block. It will usually not block when reading from a file because the contents of it are readily available (i.e., inputStream.available() > 0), they are on your machine after all. However, if you construct a Scanner using an InputStream that may require waiting for data to arrive (e.g., reading text from a remote client, waiting for a page to load so you can read its source, etc.) then Scanner#nextLine() will block because it needs to wait for enough information to build the next line to arrive.
It blocks if it's reading from a network and there is no data or no newline present in the input and it hasn't reached EOS. You must be reading from a file.
The question is similar to the following two questions.
Java InputStream blocking read
Why is the FileInputStream read() not blocking?
But I still cannot fully understand it.
So far I think the read() method in following code will block due to the empty file 'test.txt'.
FileInputStream fis = new FileInputStream("c:/test.txt");
System.out.println(fis.read());
System.out.println("to the end");
Actually it will print -1, I want to know why.
The javadoc says This method blocks if no input is yet available.
What does 'no input is available' mean?
thanks.
The answer to your question can be found in the JavaDoc for .read():
This method blocks if no input is yet available.
and
Returns: the next byte of data, or -1 if the end of the file is reached.
So, an empty file will get you an immediate -1 (instead of read() blocking) as
there is input available, since the file exists
...but it is empty, so immediate EOF.
The ...No input is yet available... situation could occur eg. when one was to read from a named pipe instead of a plain file, and the other side of the pipe hasn't written anything yet.
Cheers,
FileInputStream can be used to read from things other than ordinary files. One obvious example is a named pipe: if you try to read from a pipe before the other side has written to it, the read operation will block.
This maybe interperted as follows: FileInputStream.read invokes a native method, the native method makes the read system call and blocks waiting for OS to read the bytes from file into a buffer and returns when ready. That is, FileInputStream.read uses synchronous I/O to reads data from a file as opposed to non-blocking, asynchronous I/O.
You can't interpret 'no input is available' as 'you are positioned at EOF and no more input will ever be available'. They are different conditions. The latter returns -1.
In general, all reads from files block until the data is available. The disk has to come around to the right point and the head has to seek to the right track. You also need to consider files that are on shared drives, or files that are named pipes, both of which involve network operations, which can also block.
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?
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.
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
I am using the javax.comm package to perform read and write operations on the SerialPort.
I have created an object of type InputStream as InputStream in;
My question is ....
Irrespective of data availibility on the SerialPort, in.available() always returns a zero due to which I am not able to decide whether bytes are available or not.
If i use the in.read() directly, it seems to block the execution forever..
Please help...
Awaiting your reply..
You can also mail me on my email address..
In anticipation of your reply....
Utsav
This is typical behavior of block I/O. The read() is going to block till some bytes are available, EOF or error. You should create a new thread and just wait for more data.
Don't use available() call because it may create a fast loop and drive up your CPU usage. If you really want do this in a single thread, looking into NIO.