The javadoc for Scanner.hasNextLine()
states:
Returns true if there is another line in the input of this scanner. This method m
How to decide if it will block?
To decide if hasNextLine
will block or not is unfortunately not a supported use case.
This is because the underlying sources doesn't always provide an API for peeking in the stream. Put differently, the implementation of hasNextLine
calls methods that themselves may block so the problem is sort of inherent.
So, what to do?
If this is indeed a required use case, I would recommend one of the following approaches:
Make sure the conditions are right for the hasNextLine
. Only provide the scanner with sources that have a definite end (such as a file or string) and never an "open ended" input such as System.in
.
If this is part of an API you could wrap the scanner in your own class that only exposes "safe" constructors.
Roll your own class from scratch that does have a willHasNextLineBlock
type of method. This could probably be implemented somewhat robustly using InputStream.available.
Under the category of super ugly workarounds we find:
Making an attempt at calling hasNextLine
in a separate thread and see if it returns within reasonable time, as follows:
boolean wouldBlock = false;
Thread t = new Thread(() -> s.hasNextLine());
t.start();
try {
t.join(100);
} catch (InterruptedException e) {
wouldBlock = true;
}
Use a custom input stream (something like a peekable stream that one could tap into before calling hasNextLine
. Something like the this
CustomStream wrapped = new CustomStream(originalSource)
Scanner s = new Scanner(wrapped);
...
if (wrapped.hasNextLine())
// s.hasNextLine would not block
else
// s.hasNextLine would block
(Note however that this is somewhat unsafe, since the scanner may have buffered some data from the CustomStream
.)