Submitted On 06-NOV-1997
c23kab
It appears that by using the BufferedReader constructor that
allows the buffer size to be specified (instead of using the
constructor that sets the default size) and by setting the
buffer size to '1', the problem goes away: BufferedReader
in = new BufferedReader(new InputStreamReader(System.in),1);
It acts as if the Windows '95 implementation uses full
buffering instead of line buffering and this will not work
for an interactive stream. The readLine() documentation
certainly implies line buffering.
Submitted On 20-NOV-1997
stevenmz
Specify a buffer size of one byte in the constructor.
BufferedReader in = new BufferedReader(new FileReader("foo.in"), 1)
Submitted On 22-NOV-1997
dorvocho
What is the point of having a buffer if you set
it's size to 1? Is this the same bug as 4093424?
Submitted On 28-FEB-1998
s_t_e_v_e
Looks like a duplicate of 4080163 to me.
Submitted On 09-APR-1998
ptomblin
Similar, but not identical (because it *doesn't* work on NT 4.0)
The following program works fine on Linux JDK 1.1.5, but on NT it
doesn't consume the input buffer at all, so when you control-C out,
everything you typed comes out as commands to the shell:
/* vim:set si sw=4 ts=4: */
import java.io.*;
import java.net.*;
import java.util.*;
public class ReadStdinNoThread
{
public static void main(String[] argv) throws Throwable
{
BufferedReader _is = new BufferedReader(new
InputStreamReader(System.in), 1);
PrintWriter _ps = new PrintWriter(System.out, true);
_ps.println("ready for input:");
try
{
while (true)
{
String in = _is.readLine();
if (in != null)
{
if (in.equals("."))
break;
_ps.println(in);
}
}
}
catch (IOException e)
{
}
_ps.println("exiting");
}
}
Submitted On 09-APR-1998
ptomblin
I withdraw my previous comment - turns out it works
fine with a regular DOS shell, it just doesn't work
with a Cygwin bash shell.
Submitted On 31-MAY-1998
jgf1
I don't think this is a bug in BufferedReader.readLine().
I also don't think it's a Windows API bug - it's quite possible to write
console applications for Windows 95 in C or Java that don't suffer from
this problem. (Even if the API was faulty, it's the low level Java code's
job to work round it - Java is meant to be portable and easy to code).
I think the bug is in System.in.available()
It seems that System.in.available() is returning an incorrect value for
the number of characters that are ready and waiting to be read. Quite
often the return value is too large, such as being 1 when there is no data
available. (Note that I haven't tested this with redirected input, just
keyboard input. Also this is all Win95 specific.)
Here's some typical keyboard input code:
// Open standard (keyboard) input as a buffered character stream.
BufferedReader stdin = new BufferedReader (new InputStreamReader (System.in));
String aLineOfText = stdin.readLine(); // get a line
The InputStream reader should, in this example, read a line at a time and
pass it to the BufferedReader. However, if two or more lines are available
then it has been designed to read in everything at once for efficiency.
Since it is sometimes being told (by System.in.available()) that there is
another line ready when there isn't, it is asking for the second line and
having to wait for the user to type it in, before the first line has been
processed.
Workaround
~~~~~~~~~~
I've come up with a few workarounds. Most elegent is to create a wrapper
class for System.in that has the same type as System.in (by inheritance
and polymorphism) and passes on every function call except available().
Since I can't find a way to get the correct value of System.in.available(),
I just return 0. This is OK if you're just using a BufferedReader.readLine()
to read the data, but is obviously not ideal.
To use this class, wrap it around System.in. For example, the code above
becomes:
// Open standard (keyboard) input as a buffered character stream.
BufferedReader stdin = new BufferedReader (new InputStreamReader (
new SystemInWrapper (System.in)));
String aLineOfText = stdin.readLine(); // get a line
This has the advantage of being portable - if you're using UNIX then the
extra wrapper class will cause a slight slowdown, but not much.
Here is the code for SystemInWrapper:
// SystemInWrapper.java
//
// By Jonathan Foster 1998
// Donated to the public domain.
//
// This class fixes the problems with newlines from System.in not being
// acted on immediately, which is a symptom of the fact that
// System.in.available() is unreliable, frequently claiming that characters
// are available when they aren't.
//
// Instead of using this to read the keyboard:
//
// // Open standard (keyboard) input as a buffered character stream.
// BufferedReader stdin = new BufferedReader (
// new InputStreamReader (
// System.in));
//
// Use this code instead:
//
// // Open standard (keyboard) input as a buffered character stream.
// BufferedReader stdin = new BufferedReader (
// new InputStreamReader (
// new SystemInWrapper (
// System.in)));
//
import java.io.*;
public class SystemInWrapper extends InputStream
{
private InputStream in;
public SystemInWrapper (InputStream newin)
{
in = newin;
}
public int read() throws IOException
{
return in.read();
}
public int read(byte b[]) throws IOException
{
return in.read(b, 0, b.length);
}
public int read(byte b[], int off, int len) throws IOException
{
return in.read(b, off, len);
}
public long skip(long n) throws IOException
{
return in.skip(n);
}
public int available() throws IOException
{
return 0; // in.available() is unreliable, so assume that
//
Submitted On 13-JUL-1998
lareed
You can add "reported against 1.1.6" to the list
but since it sounds like a Windows 95 problem it
may be a moot point.
Submitted On 31-JUL-1998
Dbr549
It seems that jgfl is on the right track. Looking atSystem.in points us to
InputStream. The source code
for InputStream shows available simply returns 0,
and is intended to be overidden.
// from java source code.... see comment in original code
public int available() throws IOException {
return 0;
}
Since this always returns zero, it seems redundant
to override this in jgfl's wrapper. Looking next
at InputStreamReader source we see this strangeness:
/**
* Tell whether the underlying byte stream is ready to be read. Return
* false for those streams that do not support available(), such as the
* Win32 console stream.
*/
private boolean inReady() {
try {
return in.available() > 0;
} catch (IOException x) {
return false;
}
}
So, since InputStream.available always returns 0,
InputStreamReader.inReady must apparently always
return false??
Also, not being a Win95 wizard what does the comment
about Win95 console mean??
Submitted On 05-OCT-1998
jgf1
Dbr549 hasn't noticed that the type of System.in is NOT InputStream. It's
actually some other class which is a subclass of InputStream, which can be
treated as an InputStream by polymorphism. The actual type varies - it's a
networking class if I run it under the Jikes debugger, or a different class in
a console window. These classes override available() so that it can return
non-zero. (To demonstrate this, do "System.out.printf(System.in);"
and observe the result)
The comment in the JDK source that Dbr549 quoted implies that when this code
was written Sun had a perfectly good solution to this problem. It suggests
that the Win32 console streams should be throwing an IOException when their
available() method is called. There is already code in the JDK to silently
handle the exception, and this is probably the easiest way for Sun to fix this
bug. It doesn't require Sun to write a "real" System.in.available(),
or any API changes.
It isn't a perfect fix - a "real" System.in.available() would be very
nice, but one that just throws an exception would work with most programs, and
those programs that fall over when System.in.available() throws an exception
would probably be affected by the existing bug anyway.
Submitted On 01-NOV-1998
dconry
I've had problems with the available() method using
all types of input streams under Win95. Under Unix
it seems to work fine, but when reading a string typed
from a DOS window it always originally returns 2. If
you read two bytes and call it again, it returns the
length of the remaining String. Puzzling.
I usually just call available and read twice to read
each line. I've found setting the buffer size to 1
takes care of readLine() pretty well, although of
course this removes any performance advantage
readLine might have had.
Submitted On 07-SEP-1999
mwoolley
I think jgf1 has analysed this problem perfectly. However, I would suggest a
simpler way of phrasing the workaround is to use an anonymous inner class
overriding FilterInputStream, ie
BufferedReader stdin = new BufferedReader (new FilterInputStream(System.in)
{
public int available() throws IOException
{
return 0;
}
});
Submitted On 20-SEP-1999
p.lavarre
Just now in the recognised Related Bugs there are 18, 1, 5, and 1 votes ...
suggesting this should be ranked higher among the Top 25 Bugs?
Submitted On 20-SEP-1999
p.lavarre
I get the idea you're not supposed to try and use the console on Win95.
We have not only this issue relegated to "priority 4" but we also at
least have the "closed, will not be fixed" issue titled
"System.err.println discards line after EOF keystroke" at
http://developer.java.sun.com/developer/bugParade/bugs/4151071.html
Submitted On 04-NOV-1999
ltmiilr
A normal implementation of available(), based on
GetNumberOfConsoleInputEvents and PeekConsoleInput,
gets trapped by the following problem: After the line's contents
and the following CR have been read, available() will return
false, although the following LF byte is still in the input buffer.
A workaround for this problem is to have a "boolean
ignore_next_LF" in the input stream, which is set when a CR
byte is read (and converted to '\n') and cleared when any
other byte is read. And when you want to read a character
and it is LF and ignore_next_LF is true, you set it to false and
retry. This way, the function available() will be reliable.
Submitted On 08-NOV-1999
miles
the failure to provide an easy, reliable readLine for System.in
was a major oversight from the beginning.
I ALWAYS have to look up how to do this. (it's bad enough
you have to use TWO subclasses to get at readLine, then
javasoft changed the whole layout between java 1.0 - 1.1.)
Why are System.in & System.out so asymmetrical in
functionality?
Inputting a line is a common test case.
We really SHOULD have had
System.in.readLine()
all along. The c example is dandy, but how about
char *str;
gets(str);
At least the c libraries did this more elegantly.
-= miles =-
Submitted On 06-DEC-1999
Parkway
One aspect of the problem is due to Sun's use of WaitForSingleObject to see if
input is
available. Firstly, this API only works with ReadConsole, not with ReadFile, so
that it will
indicate non-typing events such as shift and control keys. Secondly, this API
is broken
on Windows 95 and will never reset to indicate that no input events are
available.
Submitted On 08-MAR-2000
p.lavarre
I see here we're up to 85 votes = 60 + 18 + 1 + 5 + 1 if we
counted this together with its recognised Related Bugs.
I'd say even more bugs fall under "console does not work"
e.g. the closed-and-will-not-be-fixed
http://developer.java.sun.com/developer/bugParade/bugs/41510
71.html
says you can't trust System.err to trace execution reliably
if you also use System.in for input.
> gets(str);
Having a bug in Sun Java Windows System.in readLine
disappoints me so intensely in part because I'd like to get
away from code like C gets. That routine is sweet poison:
if the supplier of input happens to enter more chars than
(sizeof str) then suddenly my program is writing storage
maybe it does not own, whoops.
ANSI C gave us stdio.fgets to limit the size of an entry,
Sun Java gives us more robust code to use with files, but
this supposedly more robust code breaks down if used with
an interactive stream like the Windows System.in stream.
Submitted On 07-DEC-2000
p.lavarre
The BugParade vote to supply console i/o that works is up
to 103 = 78+18+1+5+1 now. (An off-topic post in a *java*
Usenet group inspired me to check.)
Submitted On 06-FEB-2001
ChennaR
I am getting java.exe error while running a client program, consists of bufferReader.
Submitted On 30-MAY-2001
j-son
There's a known bug in Visual C++ 6.x (and 5.x?) with
getline( cin, ...); this may have something to do with the
described problem if the JDK native libraries were compiled
with VC++. See
http://support.microsoft.com/support/kb/articles/Q240/0/15.ASP?LN=EN-US&SD=gn&FR=0&qry=getline%20cin&rnk=2&src=DHCS_MSPSS_gn_SRCH&SPR=VCC
This even proposes a C++ workaround; perhaps this can be
worked around in Java instead?
Submitted On 16-JUN-2001
p.lavarre
I don't yet see a cross-ref here to:
"java.io: Add support for non-blocking I/O"
http://developer.java.sun.com/developer/bugParade/bugs/40750
58.html
Mind you, that bug Sun has now closed in favour:
"JSR-51: New I/O APIs for the JavaTM Platform"
http://java.sun.com/aboutJava/communityprocess/jsr/jsr_051_i
oapis.html
Submitted On 22-JUN-2001
p.lavarre
I see here we're up to 118 votes = 93 + 18 + 5 + 1 + 1 if
we counted this together with its recognised Related Bugs.
Submitted On 22-JUN-2001
p.lavarre
> > WED MAY 30 03:18 P.M. 2001
> > j-son
> >
http://support.microsoft.com/support/kb/articles/Q240/0/15.A
SP?LN=EN-US&SD=gn&FR=0&qry=getline%
20cin&rnk=2&src=DHCS_MSPSS_gn_SRCH&SPR=VCC
>
> [In MS VC 6 ...]
> The Standard C++ Library template getline
> function reads an extra character
> after [EOL] ...
Ouch. I hope this is not directly relevant. I can believe
getting confused over what System.in.available should say
after reading the CR of a CR LF is part of what we're
discussing here, per the analysis and workaround in the web
Comment here above stamped "SUN MAY 31 06:03 A.M.
1998", "jgf1".
Strange that the Evaluation here above stamped "9/14/1998"
claims there is "no effective workaround" ... I wonder
what's wrong with the "... MAY 31 ... 1998" workaround
claimed here?
Submitted On 22-JUN-2001
p.lavarre
Ahhhh, sorry to be so confused. I think the closed-as-
duplicate-trail is corrupt here. I now believe the root
entry in the bugParade/ for:
New I/O APIs for the JavaTM Platform
http://jcp.org/jsr/detail/051.jsp
is:
bugs/4286936.html
There I've just added as a web comment my claim that email
from jsr-51-comments at jcp.org assures me we shouldn't
read jsr/detail/051.jsp to suggest any intention of
providing cross-platform console i/o that works even as
well as the fgets/fputs of C.
Submitted On 14-FEB-2002
supalov
Hi!
Looks like Sun prefers to forget about Win 95 (and many
other Windows, I suppose). If a bug is still there since
August 1997 (I submitted a related one as late as November
2001!!!), something must be wrong.
And, frankly, effectively disabling the buffering may not be
considered a good workaround. It's just easier than to put a
flush after every write, but it's still UGLY as it defeats
the whole reason for having a buffer in the first place.
Best regards.
Alexander
Submitted On 03-JUN-2002
dconry
Closed, will not be fixed? I guess Windows 9x isn't an important enough platform...
Submitted On 17-DEC-2002
p.lavarre
This bug is "closed, will not be fixed" with 103 votes.
I wonder how many of those votes would happily move to:
Improved interactive console I/O ...
http://developer.java.sun.com/developer/bugParade/
bugs/4050435.html
Submitted On 25-JUL-2007
minati
Please provide me the code how to compare two file . Suppose there are 3 file.We compare file1 with file2 line by line(Row wise). Suppose i compare logonid(unique) of file1 with file2. If logonid is match then copy the entire row to file3. Please tell me the what is the code for it.
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|