The Standard Input, Output, and Error Streams
The standard output stream (usually the display) is represented by the PrintStream object System.out. The standard input stream (usually the keyboard) is represented by the InputStream object System.in. In other words, it is a byte input stream. The standard error stream (also usually the display) is represented by System.err, which is another object of the PrintStream class. The PrintStream class offers print() methods that act as corresponding print() methods from the PrintWriter class. The print() methods can be used to write output to System.out and System.err. In other words, both System.out and System.err act like PrintWriter, but in addition they have write() methods for writing bytes.
The System class provides the methods setIn(InputStream), setOut(PrintStream), and setErr(PrintStream) that can be passed an I/O stream to reassign the standard streams.
In order to read characters typed by the user, the Console class is recommended (p. 1256).
Comparison of Byte Streams and Character Streams
It is instructive to see which byte streams correspond to which character streams. Table 20.7 shows the correspondence between byte and character streams. Note that not all classes have a corresponding counterpart.
Table 20.7 Correspondence between Selected Byte and Character Streams
Byte streams | Character streams |
OutputStream | Writer |
InputStream | Reader |
No counterpart | OutputStreamWriter |
No counterpart | InputStreamReader |
FileOutputStream | FileWriter |
FileInputStream | FileReader |
BufferedOutputStream | BufferedWriter |
BufferedInputStream | BufferedReader |
PrintStream | PrintWriter |
DataOutputStream | No counterpart |
DataInputStream | No counterpart |
ObjectOutputStream | No counterpart |
ObjectInputStream | No counterpart |
20.4 The Console Class
A console is a unique character-based device associated with a JVM. Whether a JVM has a console depends on the platform, and also on the manner in which the JVM is invoked. When the JVM is started from a command line, and the standard input and output streams have not been redirected, the console will normally correspond to the keyboard and the display (Figure 20.8). In any case, the console will be represented by an instance of the class java.io.Console. This Console instance is a singleton, and can only be obtained by calling the static method console() of the System class. If there is no console associated with the JVM, the null value is returned by this method.
Figure 20.8 Keyboard and Display as Console
// Obtaining the console:
Console console = System.console();
if (console == null) {
System.err.println(“No console available.”);
return;
}
// Continue …
For creating dialogue for console-based applications, the Console class provides the following functionality:
- Prompt and read a line of character-based response.
String username = console.readLine(“Enter the username (%d chars): “, 4);
The readLine() method first prints the formatted prompt on the console, and then returns the characters typed at the console when the line is terminated by the ENTER key.
- Prompt and read passwords without echoing the characters on the console.
char[] password;
do {
password = console.readPassword(“Enter password (min. %d chars): “, 6);
} while (password.length < 6);
The readPassword() method first prints the formatted prompt, and returns the password characters typed by the user in an array of char when the line is terminated by the ENTER key. The password characters are not echoed on the display.
Since a password is sensitive data, one recommended practice is to have it stored in memory for only as long as it is necessary and to zero-fill the char array as soon as possible in order to overwrite the password characters.
- Print formatted values to the console.
Similar to the PrintWriter and the PrintStream classes, the Console class also provides the format() and the printf() methods for printing formatted values, but its methods do not allow a locale to be specified.
Note that the console only returns character-based input. For reading other types of values from the standard input stream, the java.util.Scanner class can be considered.
The Console class provides methods for formatted prompting and reading from the console, and obtaining the reader associated with it.
String readLine()
String readLine(String format, Object… args)
The first method reads a single line of text from the console. The second method prints a formatted prompt first, then reads a single line of text from the console. The prompt is constructed by formatting the specified args according to the specified format.
char[] readPassword()
char[] readPassword(String format, Object… args)
The first method reads a password or a password phrase from the console with echoing disabled. The second method does the same, but first prints a formatted prompt.
Reader reader()
This retrieves the unique Reader object associated with this console.
The Console class provides the following methods for writing formatted strings to the console, and obtaining the writer associated with it:
Console format(String format, Object… args)
Console printf(String format, Object… args)
Write a formatted string to this console’s output stream using the specified format string and arguments, according to the default locale. See the PrintWriter class with analogous methods (p. 1245).
PrintWriter writer()
Retrieves the unique PrintWriter object associated with this console.
void flush()
Flushes the console and forces any buffered output to be written immediately.
Example 20.5 illustrates using the Console class to change a password. The example illustrates the capability of the Console class, and in no way should be construed to provide the ultimate secure implementation to change a password.
The console is obtained at (1). The code at (2) implements the procedure for changing the password. The user is asked to submit the new password, and then asked to confirm it. Note that the password characters are not echoed. The respective char arrays returned with this input are compared for equality by the static method equals() in the java.util.Arrays class, which compares two arrays.
Example 20.5 Changing Passwords
import java.io.Console;
import java.io.IOException;
import java.util.Arrays;
/** Class to change the password of a user */
public class ChangePassword {
public static void main (String[] args) throws IOException {
// Obtain the console: (1)
Console console = System.console();
if (console == null) {
System.err.println(“No console available.”);
return;
}
// Changing the password: (2)
boolean noMatch = false;
do {
// Read the new password and its confirmation:
char[] newPasswordSelected
= console.readPassword(“Enter your new password: “);
char[] newPasswordConfirmed
= console.readPassword(“Confirm your new password: “);
// Compare the supplied passwords:
noMatch = newPasswordSelected.length == 0 ||
newPasswordConfirmed.length == 0 ||
!Arrays.equals(newPasswordSelected, newPasswordConfirmed);
if (noMatch) {
console.format(“Passwords don’t match. Please try again.%n”);
} else {
// Necessary code to change the password.
console.format(“Password changed.”);
}
} while (noMatch);
}
}
Running the program:
>
java ChangePassword
Enter your new password:
Confirm your new password:
Password changed.