Java™ 教程(命令列I/O)

博弈發表於2019-01-19

命令列I/O

程式通常從命令列執行,並在命令列環境中與使用者互動,Java平臺以兩種方式支援這種互動:通過標準流和控制檯。

標準流

標準流是許多作業系統的一個特性,預設情況下,它們從鍵盤讀取輸入並將輸出寫入顯示器,它們還支援檔案和程式之間的I/O,但該功能由命令列直譯器控制,而不是程式。

Java平臺支援三種標準流:標準輸入,可通過System.in訪問;標準輸出,可通過System.out訪問;和標準錯誤,通過System.err訪問。這些物件是自動定義的,不需要開啟,標準輸出和標準錯誤均用於輸出,單獨具有錯誤輸出允許使用者將常規輸出轉移到檔案並仍然能夠讀取錯誤訊息,有關更多資訊,請參閱命令列解釋程式的文件。

你可能希望標準流是字元流,但由於歷史原因,它們是位元組流,System.outSystem.err定義為PrintStream物件,雖然從技術上講它是位元組流,但PrintStream利用內部字元流物件來模擬字元流的許多功能。

相比之下,System.in是一個沒有字元流功能的位元組流,要將標準輸入用作字元流,請在InputStreamReader中包裝System.in

InputStreamReader cin = new InputStreamReader(System.in);

控制檯

控制檯是標準流的更高階替代方案,這是一個型別為Console的單獨、預定義的物件,它具有標準流提供的大部分功能,以及其他功能。控制檯對於安全密碼輸入特別有用,Console物件還通過其readerwriter方法提供真正的字元流的輸入和輸出流。

在程式可以使用控制檯之前,它必須通過呼叫System.console()來嘗試檢索Console物件,如果Console物件可用,則此方法將返回該物件,如果System.console返回NULL,則不允許使用Console操作,因為作業系統不支援它們,或者因為程式是在非互動式環境中啟動的。

Console物件通過其readPassword方法支援安全密碼輸入,此方法有助於以兩種方式保護密碼輸入,首先,它抑制回顯,因此密碼在使用者螢幕上不可見,其次,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類遵循以下步驟:

  1. 嘗試檢索Console物件,如果物件不可用,則中止。
  2. 呼叫Console.readLine以提示並讀取使用者的登入名。
  3. 呼叫Console.readPassword以提示並讀取使用者的現有密碼。
  4. 呼叫verify以確認使用者有權更改密碼(在此示例中,verify是一個始終返回true的虛方法)。
  5. 重複以下步驟,直到使用者輸入兩次相同的密碼:

    • 呼叫Console.readPassword兩次以提示並讀取新密碼。
    • 如果使用者兩次都輸入相同的密碼,請呼叫change以進行更改(同樣,change是一種虛擬方法)。
    • 用空格覆蓋這兩個密碼。
  6. 用空格覆蓋舊密碼。

上一篇:格式化流

下一篇:資料流

相關文章