When Does Scanner.nextLine() block? - java

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.

Related

What happens if I do not close BufferedReader in java? (Stream type reading in multi-threaded program)

I have a multi-threaded program, in which I open a BufferedReader to read content from FIFO(named Pipe) file. As I want to implement stream type of solution to read text from FIFO file continuously, I have created a BufferedReader outside of thread task run, and want to keep that open forever as long as application is running.(No close() on bufferedReader)
With the limited(let say 10) threads in ThreadPool will keep look for text in FIFO file and process that text for further. As I am using FIFO it will never reach END OF FILE.
By doing this, For a smaller input file it reads successfully, for a large input file it throws Stream closed IOexception(sporadically). It close automatically, I do not have close() statement.
I have a code in place to acquire and close the semaphore lock at the place where i use br.readLine() to handle race condition issue
java.io.IOException: Stream closed
at java.io.BufferedReader.ensureOpen(BufferedReader.java:122) ~[?:1.8.0_152]
at java.io.BufferedReader.readLine(BufferedReader.java:317) ~[?:1.8.0_152]
at java.io.BufferedReader.readLine(BufferedReader.java:389) ~[?:1.8.0_152]
Question:
For this solution I do not want to close the BufferedReader. What are the consequences?
Can I have a bufferedReader which never be closed? if so what steps I should consider in code.
BufferedReader is not a thread-safe class, so, we can get an uncountable number of various error on attempt to use the same object of that class from different threads.

Is InputStream.available() supposed to block?

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.

when does FileInputStream.read() block?

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?

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

How do i check if inputstream contains no data?

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.

Categories

Resources