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

标准流

标准流是许多操作系统的功能。默认情况下,它们从键盘读取输入,并将输出写入显示器。它们还支持文件和程序之间的I / O,但是该功能由命令行解释器而不是程序控制。
Java平台支持三种标准流:标准输入(Standard Input,通过System.in访问; 标准输出(Standard Output,通过System.out;访问 和标准错误(Standard Error,可通过System.err访问。这些对象是自动定义的,不需要打开。标准输出和标准错误均用于输出。具有错误输出的功能使用户可以将常规输出转移到文件中,并且仍然能够读取错误消息。有关更多信息,请参阅命令行解释器的文档。
您可能希望标准流是字符流,但是由于历史原因,它们是字节流。System.outSystem.err被定义为 PrintStream对象。尽管从技术上讲它是字节流,但PrintStream利用内部字符流对象来模拟字符流的许多功能。
相反,System.in是没有字符流功能的字节流。要使用标准输入作为字符流,请将System.in包装在InputStreamReader

  1. InputStreamReader cin = new InputStreamReader(System.in);

控制台

标准流的一种更高级的替代方法是控制台(Console)。这是一个预定义的Console类型的对象 ,具有标准流提供的大多数功能以及其他功能。控制台对于安全密码输入特别有用。Console对象还通过其readerwriter方法提供了输入和输出流,它们是真正的字符流。
在程序可以使用控制台之前,它必须尝试通过调用System.console()来检索Console对象。如果Console对象可用,则此方法返回它。如果System.console返回NULL,则由于操作系统不支持控制台操作或由于该程序是在非交互式环境中启动的,因此不允许进行控制台操作。
Console对象通过readPassword方法支持安全密码输入。此方法以两种方式帮助保护密码输入。首先,它禁止了回显,因此密码在用户屏幕上不可见。其次,readPassword返回一个字符数组,而不是一个String,因此可以覆盖密码,并在不再需要时将其从内存中删除。
Password示例是用于更改用户密码的原型程序。它演示了几种Console方法。

  1. import java.io.Console;
  2. import java.util.Arrays;
  3. import java.io.IOException;
  4. public class Password {
  5. public static void main (String args[]) throws IOException {
  6. Console c = System.console();
  7. if (c == null) {
  8. System.err.println("No console.");
  9. System.exit(1);
  10. }
  11. String login = c.readLine("Enter your login: ");
  12. char [] oldPassword = c.readPassword("Enter your old password: ");
  13. if (verify(login, oldPassword)) {
  14. boolean noMatch;
  15. do {
  16. char [] newPassword1 = c.readPassword("Enter your new password: ");
  17. char [] newPassword2 = c.readPassword("Enter new password again: ");
  18. noMatch = ! Arrays.equals(newPassword1, newPassword2);
  19. if (noMatch) {
  20. c.format("Passwords don't match. Try again.%n");
  21. } else {
  22. change(login, newPassword1);
  23. c.format("Password for %s changed.%n", login);
  24. }
  25. Arrays.fill(newPassword1, ' ');
  26. Arrays.fill(newPassword2, ' ');
  27. } while (noMatch);
  28. }
  29. Arrays.fill(oldPassword, ' ');
  30. }
  31. // Dummy change method.
  32. static boolean verify(String login, char[] password) {
  33. // This method always returns
  34. // true in this example.
  35. // Modify this method to verify
  36. // password according to your rules.
  37. return true;
  38. }
  39. // Dummy change method.
  40. static void change(String login, char[] password) {
  41. // Modify this method to change
  42. // password according to your rules.
  43. }
  44. }

Password类的步骤如下:

  1. 尝试检索Console对象。如果对象不可用,请中止。
  2. 调用Console.readLine以提示并读取用户的登录名。
  3. 调用Console.readPassword以提示并阅读用户的现有密码。
  4. 调用verify以确认用户有权更改密码。(在此示例中,verify是一个始终返回true的伪方法。)
  5. 重复以下步骤,直到用户两次输入相同的密码:
    1. 调用Console.readPassword两次,以提示输入并读取新密码。
    2. 如果用户两次输入相同的密码,请调用change以更改它。(同样,change是一个虚拟方法。)
    3. 用空格覆盖(Overwrite)两个密码。
  6. 用空格覆盖旧密码。