Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2033377 | 1.4.0 | Michael Mccloskey | P4 | Closed | Fixed | beta |
Name: skT45625 Date: 04/12/2000
java version "1.3.0rc2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0rc2-Y)
Java HotSpot(TM) Client VM (build 1.3.0rc2-Y, mixed mode)
I was trying to find a non-threaded solution to timeout reading input from the
System.in. After a good bit of experimentation, I determined that the code
appearing below SHOULD work. Unfortunately, it does not work on win32 systems
because the BufferedReader implementation -- at least in jdk1.3rc2 -- does not
correctly (or at least to my liking) implement the semantics of readLine().
The API docs for readLine state: "Read a line of text. A line is considered to
be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a
carriage return followed immediately by a linefeed." This gives one (one being
me in this case) the impression that the entire line-termination sequence will
consumed. On win32 systems, line-termination is "\r\n", two characters.
Unfortunately, the implementation does not consume both characters immediately.
It finds the carriage return but leaves the newline in the buffer. As a result,
ready() returns true but the subsequent read blocks when the only content in
the buffer is the second half of the win32 line termination sequence.
Here is the correct but, on win32 systems, non-working code. Note that this
code DOES work as expected on jdk1.2.2.
---------- TimedReader.java ----------
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.Reader;
import java.io.IOException;
public class TimedReader {
public static void main(String[] args) {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(isr);
while (true) {
try {
System.out.print("Enter a String: ");
if (ready(in, 5000)) {
String s = in.readLine();
} else {
System.out.println("timeout");
}
} catch (IOException e) {
// ignore until we know what to do
}
}
}
public static boolean ready(Reader in, long timeout) throws IOException {
while (true) {
long now = System.currentTimeMillis();
try {
while (in.ready() == false && timeout > 0) {
Thread.sleep(100);
timeout -= 100;
}
return in.ready();
} catch (IOException e) {
throw e;
} catch (Exception e) {
// ignore
} finally {
// adjust timer by length of last nap
timeout -= System.currentTimeMillis() - now;
}
}
}
}
---------- end ----------
(Review ID: 103613)
======================================================================
- backported by
-
JDK-2033377 BufferedReader.ready() returns true when readLine() will block
-
- Closed
-
- duplicates
-
JDK-4318174 BufferedReader.readLine() returns null although ready() returns true
-
- Closed
-
-
JDK-4348214 BufferedReader.ready() is not detecting the removal of data off the stream.
-
- Closed
-