While the print methods of System.out
are simple and convenient to use, a shortcoming often cited
by new Java users has been the lack of a comparabe set of text
input methods. Fortunately, J2SE 5.0 comes with the new Scanner
class that we discuss it in the next section.
Here we examine the standard text input techniques available with
Java 1.4 and earlier.
System.in offers only the very limited capabilities of
an InputStream.
You can, for example, read in a single byte, which returns
as an int
value, or a byte
array. You must cast each byte obtained from the keyboard to a
char type.
For example:
try {
int tmp = System.in.read ();
char c = (char) tmp;
}
catch (IOException e) {}
Here a byte value is read and returned as the first byte
in an int
value. This value is then converted to a char
value. This assumes that the byte corresponds to an 8-bit encoded
character, such as an ASCII character. As for most Java I/O operations,
you must enclose the read()
method in a try-catch
block to catch any possible IOException
that might be thrown.
To read a string of characters the above code segment
should go inside a loop, as in
String strInput
= "";
while (true) {
try {
int tmp = System.in.read ();
if (tmp == -1) break;
char c = (char) tmp;
strInput
= strInput + c;
}
catch (IOException e) {}
}
System.out.println ("Echo = " + strInput);
The
return of a -1 value indicates the end of the input. Since the
byte that is read goes into the first 8 bits of a 32-bit int
value, a genuine data value can never set the sign bit.
We see that System.in
is obviously an inelegant and inefficient way to carry out routine
text input. We therefore normally wrap this input stream with
classes that provide more powerful methods.
As discussed an earlier section,,
the buffer wrapper classes provide for efficient transmission
of stream bytes. In addition, they typically add various useful
methods. In the BufferedReaderApp
example, we wrap System.in
with the InputStreamReader
and then wrap this instance with BufferedReader.
We take advantage of the readLine()
method in BufferedReader
and obtain a whole line of input all at once rather than looping
over reads of one character at a time. This technique also removes
the need for type conversion from int
to char.
|
import
java.io.*;
/**
* Demonstrate the BufferedReader class for
wrapping a
* reader object and providing the readLine
() method.
**/
public class BufferedReaderApp
{
public static void main (String arg[]) {
// System.in std input stream
already opened by default.
// Wrap in a new reader stream
to obtain 16 bit capability.
InputStreamReader reader = new
InputStreamReader (System.in);
// Wrap the reader with a buffered
reader.
BufferedReader buf_in = new BufferedReader
(reader);
// Wrap in a new writer stream
to obtain 16 bit capability.
OutputStreamWriter writer = new
OutputStreamWriter (System.out);
// PrintWriter wrapper
PrintWriter print_writer = new
PrintWriter (writer, true);
String str = "q";
try {
// Read a whole line
a time. Check the string for
// the "quit" input
to jump from the loop.
do {
// Read
text from keyboard
str =
buf_in.readLine ();
// Echo
the text back to console.
print_writer.println
("echo " + str);
} while (!str.toLowerCase
().equals ("q") );
}
catch (IOException
e) {
System.out.println
("IO exception = " + e );
}
} // main
} // class BufferedReaderApp
|
A session with BufferedReaderApp
could go as follows:
My
input from the keyboard
echo My input from the keyboard
More of my input
echo More of my input
q
echo q
To obtain numerical values from the keyboard requires
reading the values as strings and then converting them to primitive
types. For example, the following snippet reads in an integer
value as a string and then converts it to an int value.
InputStreamReader reader = new InputStreamReader (System.in);
BufferedReader buf_reader = new BufferedReader (reader);
try {
String s = buf_reader.readLine (); // read the number
as a string
// Trim the whitespace before parsing.
tmp = Integer.parseInt (s.trim ()); // Convert string
to int
System.out.println (" echo = " + tmp);
}
catch (IOException ioe) {
System.out.println ("IO exception = " + ioe);
}
Similar code is needed for parsing other numerical
input according to the type of values. The text section
discusses an easier technique for numerical input using the Scanner
class of J2SE 5.0.
References and Web
Resources
Latest update: Dec. 9, 2004
|