Documentation

The Java™ Tutorials
Hide TOC
I/O from the Command Line来自命令行的I/O
Trail: Essential Java Classes
Lesson: Basic I/O
Section: I/O Streams

I/O from the Command Line来自命令行的I/O

A program is often run from the command line and interacts with the user in the command line environment. 程序通常从命令行运行,并在命令行环境中与用户交互。The Java platform supports this kind of interaction in two ways: through the Standard Streams and through the Console.Java平台通过两种方式支持这种交互:通过标准流和通过控制台。

Standard Streams标准流

Standard Streams are a feature of many operating systems. 标准流是许多操作系统的一个特性。By default, they read input from the keyboard and write output to the display. 默认情况下,它们从键盘读取输入,并将输出写入显示器。They also support I/O on files and between programs, but that feature is controlled by the command line interpreter, not the program.它们还支持文件和程序之间的I/O,但该功能由命令行解释器控制,而不是由程序控制。

The Java platform supports three Standard Streams: Standard Input, accessed through System.in; Standard Output, accessed through System.out; and Standard Error, accessed through System.err. Java平台支持三种标准流:标准输入,通过System.in访问;标准输出,通过System.out访问;和标准错误,通过System.err访问。These objects are defined automatically and do not need to be opened. 这些对象是自动定义的,不需要打开。Standard Output and Standard Error are both for output; having error output separately allows the user to divert regular output to a file and still be able to read error messages. 标准输出和标准误差均为输出;单独设置错误输出允许用户将常规输出转移到文件,并且仍然能够读取错误消息。For more information, refer to the documentation for your command line interpreter.有关更多信息,请参阅命令行解释器的文档。

You might expect the Standard Streams to be character streams, but, for historical reasons, they are byte streams. 您可能希望标准流是字符流,但出于历史原因,它们是字节流。System.out and System.err are defined as PrintStream objects. System.outSystem.err被定义为PrintStream对象。Although it is technically a byte stream, PrintStream utilizes an internal character stream object to emulate many of the features of character streams.尽管从技术上讲,PrintStream是一个字节流,但它利用一个内部字符流对象来模拟字符流的许多特性。

By contrast, System.in is a byte stream with no character stream features. 相较之下,System.in是一个没有字符流特性的字节流。To use Standard Input as a character stream, wrap System.in in InputStreamReader.要将标准输入用作字符流,请在InputStreamReader中包装System.in

InputStreamReader cin = new InputStreamReader(System.in);

The Console控制台

A more advanced alternative to the Standard Streams is the Console. 标准流的更高级替代品是控制台。This is a single, predefined object of type Console that has most of the features provided by the Standard Streams, and others besides. 这是一个预定义的Console类型的对象,它具有标准流提供的大多数特性,以及其他特性。The Console is particularly useful for secure password entry. 控制台对于安全的密码输入特别有用。The Console object also provides input and output streams that are true character streams, through its reader and writer methods.Console对象还通过其reader方法和writer方法提供作为真实字符流的输入和输出流。

Before a program can use the Console, it must attempt to retrieve the Console object by invoking System.console(). 在程序可以使用控制台之前,它必须通过调用System.Console()尝试检索控制台对象。If the Console object is available, this method returns it. 如果Console对象可用,此方法将返回它。If System.console returns NULL, then Console operations are not permitted, either because the OS doesn't support them or because the program was launched in a noninteractive environment.如果System.console返回NULL,则不允许控制台操作,因为操作系统不支持这些操作,或者因为程序是在非交互环境中启动的。

The Console object supports secure password entry through its readPassword method. Console对象通过其readPassword方法支持安全密码输入。This method helps secure password entry in two ways. 此方法通过两种方式帮助确保密码输入的安全。First, it suppresses echoing, so the password is not visible on the user's screen. 首先,它抑制回音,因此密码在用户屏幕上不可见。Second, readPassword returns a character array, not a String, so the password can be overwritten, removing it from memory as soon as it is no longer needed.其次,readPassword返回一个字符数组,而不是String,因此密码可以被覆盖,一旦不再需要,就从内存中删除。

The Password example is a prototype program for changing a user's password. Password示例是用于更改用户密码的原型程序。It demonstrates several Console methods.它演示了几种Console方法。

import java.io.Console;
import java.util.Arrays;
import java.io.IOException;

public class Password {
    
    public static void main (String args[]) throws IOException {

        Console c = System.console();
        if (c == null) {
            System.err.println("No console.");
            System.exit(1);
        }

        String login = c.readLine("Enter your login: ");
        char [] oldPassword = c.readPassword("Enter your old password: ");

        if (verify(login, oldPassword)) {
            boolean noMatch;
            do {
                char [] newPassword1 = c.readPassword("Enter your new password: ");
                char [] newPassword2 = c.readPassword("Enter new password again: ");
                noMatch = ! Arrays.equals(newPassword1, newPassword2);
                if (noMatch) {
                    c.format("Passwords don't match. Try again.%n");
                } else {
                    change(login, newPassword1);
                    c.format("Password for %s changed.%n", login);
                }
                Arrays.fill(newPassword1, ' ');
                Arrays.fill(newPassword2, ' ');
            } while (noMatch);
        }

        Arrays.fill(oldPassword, ' ');
    }
    
    // Dummy change method.
    static boolean verify(String login, char[] password) {
        // This method always returns
        // true in this example.
        // Modify this method to verify
        // password according to your rules.
        return true;
    }

    // Dummy change method.
    static void change(String login, char[] password) {
        // Modify this method to change
        // password according to your rules.
    }
}

The Password class follows these steps:Password类遵循以下步骤:

  1. Attempt to retrieve the Console object. 尝试检索Console对象。If the object is not available, abort.如果对象不可用,中止。
  2. Invoke Console.readLine to prompt for and read the user's login name.调用Console.readLine提示并读取用户的登录名。
  3. Invoke Console.readPassword to prompt for and read the user's existing password.调用Console.readPassword以提示并读取用户的现有密码。
  4. Invoke verify to confirm that the user is authorized to change the password. 调用verify以确认用户有权更改密码。(In this example, verify is a dummy method that always returns true.)(在本例中,verify是一个始终返回true的伪方法。)
  5. Repeat the following steps until the user enters the same password twice:重复以下步骤,直到用户输入相同密码两次:
    1. Invoke Console.readPassword twice to prompt for and read a new password.调用Console.readPassword两次以提示输入和读取新密码。
    2. If the user entered the same password both times, invoke change to change it. 如果用户两次都输入了相同的密码,请调用change来更改密码。(Again, change is a dummy method.)(同样,change是一种虚拟方法。)
    3. Overwrite both passwords with blanks.用空格覆盖两个密码。
  6. Overwrite the old password with blanks.用空格覆盖旧密码。

Previous page: Formatting
Next page: Data Streams