System.in.read() 指南
1. 概述
Java 提供了多種工具和功能來處理使用者輸入。 System.in.read()
是從控制台讀取輸入的常用方法之一。在本文中,我們將探討它的功能以及如何在 Java 中使用它。
2.什麼是System.in.read()
?
Java 方法System.in.read()
從標準輸入流讀取一個字節,通常連結到鍵盤或其他來源。它是System
類別的一部分,提供讀取面向位元組的輸入的低階機制:
public static int read() throws IOException
這裡,該方法傳回一個整數,表示讀取的字元的 ASCII 值。我們需要將 ASCII 整數值轉換為字元才能看到實際值。如果已到達流末尾,則返回-1
。
要注意的是, System.in.read()
一次只讀取一個位元組。如果我們需要讀取整行或處理不同的資料類型,我們可能需要使用其他方法或類別,例如BufferedReader
或Scanner.
3. 其他輸入來源
雖然System.in
通常用於控制台輸入, System.in.read()
也可以重定向以從各種其他來源讀取,包括檔案、網路連接和使用者介面。
這些替代輸入來源支援廣泛的應用程序,例如讀取設定檔、管理客戶端-伺服器通訊、與資料庫互動、處理使用者介面以及與感測器和物聯網設備等外部設備連接。
4. 讀取單一字符
System.in.read()
最直接的用法是讀取單一字元:
void readSingleCharacter() {
System.out.println("Enter a character:");
try {
int input = System.in.read();
System.out.println((char) input);
}
catch (IOException e) {
System.err.println("Error reading input: " + e.getMessage());
}
}
由於System.in.read()
會拋出IOException, a
已檢查的例外),因此我們需要處理它。在上面的範例中,我們捕獲IOException
並將錯誤訊息輸出到標準錯誤流。
讓我們執行一個測試,透過從輸入流讀取一個字元來確認一切都按預期工作:
@Test
void givenUserInput_whenUsingReadSingleCharacter_thenRead() {
System.setIn(new ByteArrayInputStream("A".getBytes()));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(outputStream));
SystemInRead.readSingleCharacter();
assertEquals("Enter a character:\nA", outputStream.toString().trim());
}
在這裡,我們重定向System.in.read()
以從ByteArrayInputStream
讀取。透過這樣做,我們可以避免在執行測試時提示使用者輸入,並且可以斷言控制台輸出。
5. 讀取多個字符
雖然System.in.read()
一次讀取一個字節,但我們可能經常需要讀取多個字元。常見的方法是在循環內連續讀取,直到滿足特定條件:
void readMultipleCharacters() {
System.out.println("Enter characters (Press 'Enter' to quit):");
try {
int input;
while ((input = System.in.read()) != '\n') {
System.out.print((char) input);
}
} catch (IOException e) {
System.err.println("Error reading input: " + e.getMessage());
}
}
在這裡,我們在 while 迴圈中使用System.in.read()
,該迴圈將繼續執行,直到按下 Enter 鍵。讓我們透過單元測試來測試新行為:
@Test
void givenUserInput_whenUsingReadMultipleCharacters_thenRead() {
System.setIn(new ByteArrayInputStream("Hello\n".getBytes()));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(outputStream));
SystemInRead.readMultipleCharacters();
assertEquals("Enter characters (Press 'Enter' to quit):\n" + "Hello", outputStream.toString().trim());
}
6. 帶參數的System.in.read()
System.in.read()
方法還有兩個其他版本,該方法傳回從輸入流讀取的位元組數。
6.1.讀取多個參數
此方法從輸入流讀取資料並將資料儲存在byte
組數組中,從指定的偏移量開始一直到指定的長度。如果遇到流末尾,該方法可能會讀取少於指定長度的位元組:
void readWithParameters() {
try {
byte[] byteArray = new byte[5];
int bytesRead;
int totalBytesRead = 0;
while ((bytesRead = System.in.read(byteArray, 0, byteArray.length)) != -1) {
System.out.print("Data read: " + new String(byteArray, 0, bytesRead));
totalBytesRead += bytesRead;
}
System.out.println("\nBytes read: " + totalBytesRead);
} catch (IOException e) {
e.printStackTrace();
}
}
在上面的範例中,我們從標準輸入流讀取位元組到位元組數組中,並列印讀取的位元組數和資料。我們可以執行測試來驗證其預期行為:
@Test
void givenUserInput_whenUsingReadWithParameters_thenRead() {
System.setIn(new ByteArrayInputStream("ABC".getBytes()));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(outputStream));
SystemInRead.readWithParameters();
assertEquals("Data read: ABC\n" + "Bytes Read: 3", outputStream.toString().trim());
}
6.2.讀取單一參數
此方法是System.in.read()
方法的另一個版本,它接受byte
組數組作為參數。它在內部呼叫System.in.read(byte[] b, int off, int len).
此方法使用以下簽名定義:
public static int read(byte[] b) throws IOException
7. 局限性
雖然System.in.read()
很簡單,但它有一些限制:
- 它一次只讀取一個
byte
,這使得讀取完整行或處理多字節字元的效率較低。 - 方法會阻塞,直到收到輸入。如果使用者不提供輸入,可能會導致應用程式顯得無回應。
- 對於更複雜的輸入處理,例如處理整數或字串,最好使用其他類,例如
BufferedReader
或Scanner
。
八、結論
在本文中,我們研究了 Java 中的System.in.read()
方法,並探討如何在我們的應用程式中使用它。它提供了一種基本而強大的方法來直接從標準輸入流處理使用者輸入。
透過了解其用法、處理錯誤並將其合併到更複雜的輸入場景中,我們可以建立互動式且使用者友好的應用程式。
與往常一樣,完整的源代碼可以在 GitHub 上取得。