命令行中的 I/O

程序通常从命令行运行,并在命令行环境中与用户交互。 Java 平台通过两种方式支持这种交互:通过标准流和通过控制台。

Standard Streams

标准流是许多 os 的功能。默认情况下,它们从键盘读取 Importing,并将输出写入显示器。它们还支持文件和程序之间的 I/O,但是该功能由命令行解释器而不是程序控制。

Java 平台支持三种标准流:* Standard Input ,可通过System.in访问; 标准输出,通过System.out访问;和 Standard Error *(通过System.err访问)。这些对象是自动定义的,不需要打开。标准输出和标准误差均用于输出。具有错误输出的功能使用户可以将常规输出转移到文件中,并且仍然能够读取错误消息。有关更多信息,请参阅命令行解释器的文档。

您可能希望标准流是字符流,但是由于历史原因,它们是字节流。 System.outSystem.err被定义为PrintStream个对象。尽管从技术上讲它是字节流,但PrintStream利用内部字符流对象来模拟字符流的许多功能。

相反,System.in是没有字符流功能的字节流。要将标准 Importing 用作字符流,请将System.inpackage在InputStreamReader中。

InputStreamReader cin = new InputStreamReader(System.in);

The Console

标准流的一种更高级的替代方法是控制台。这是类型为Console的单个 预定义对象,具有标准流提供的大多数功能以及其他功能。控制台对于安全密码 Importing 特别有用。 Console 对象还通过其readerwriter方法提供了 Importing 和输出流,它们是真实的字符流。

在程序可以使用控制台之前,它必须try通过调用System.console()来检索 Console 对象。如果 Console 对象可用,则此方法返回它。如果System.console返回NULL,则由于 os 不支持控制台操作或由于该程序是在非交互式环境中启动的,因此不允许进行控制台操作。

Console 对象通过其readPassword方法支持安全密码 Importing。此方法以两种方式帮助保护密码 Importing。首先,它抑制了回显,因此密码在用户屏幕上不可见。其次,readPassword返回一个字符数组,而不是String,因此可以覆盖密码,并在不再需要时将其从内存中删除。

Password示例是用于更改用户密码的原型程序。它演示了几种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.
    }
}

Password类遵循以下步骤:

  • try检索 Console 对象。如果对象不可用,请中止。

  • 调用Console.readLine提示 Importing 并读取用户的登录名。

  • 调用Console.readPassword提示并读取用户的现有密码。

  • 调用verify确认用户有权更改密码。 (在此示例中,verify是始终返回true的伪方法.)

  • 重复以下步骤,直到用户两次 Importing 相同的密码:

  • 调用Console.readPassword两次以提示 Importing 并读取新密码。

    • 如果用户两次 Importing 相同的密码,请调用change进行更改。 (同样,change是伪方法.)

    • 用空格覆盖两个密码。

  • 用空格覆盖旧密码。