Java控制台交互是入門必修課,理解流體系架構對掌握高級I/O至關重要。本文從字節流到字符流,層層遞進講解輸入輸出核心API。
System.in (InputStream) 字節流
↓ InputStreamReader (字節→字符轉換橋樑)
BufferedReader (緩衝字符流) → readLine() 逐行讀取
↓
String → Integer.parseInt() 類型轉換
// 單字符讀取
int b = System.in.read(); // 阻塞直到輸入,返回ASCII碼
char ch = (char) b;
// 批量讀取到字節數組
byte[] buffer = new byte[1024];
int len = System.in.read(buffer);
String input = new String(buffer, 0, len, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(
new InputStreamReader(System.in, StandardCharsets.UTF_8)
);
String line = reader.readLine(); // 讀取一行(不含換行符)
// 或指定編碼
BufferedReader reader = new BufferedReader(
new InputStreamReader(System.in, "GBK")
);
Scanner scanner = new Scanner(System.in, StandardCharsets.UTF_8.name());
int age = scanner.nextInt();
double score = scanner.nextDouble();
String name = scanner.next(); // 讀取下一個token(空白分隔)
String line = scanner.nextLine(); // 讀取整行
scanner.close();
public class ConsoleSum {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(
new InputStreamReader(System.in, StandardCharsets.UTF_8))) {
System.out.print("請輸入第一個整數: ");
int a = parseIntWithRetry(br, "輸入無效,請重新輸入整數: ");
System.out.print("請輸入第二個整數: ");
int b = parseIntWithRetry(br, "輸入無效,請重新輸入整數: ");
System.out.printf("%d + %d = %d%n", a, b, a + b);
} catch (IOException e) {
System.err.println("I/O錯誤: " + e.getMessage());
}
}
static int parseIntWithRetry(BufferedReader br, String retryPrompt) throws IOException {
while (true) {
try {
String line = br.readLine();
return Integer.parseInt(line.trim());
} catch (NumberFormatException e) {
System.out.print(retryPrompt);
}
}
}
}
// 格式化輸出
System.out.printf("姓名: %s, 年齡: %d, 身高: %.2f%n", name, age, height);
// 緩衝輸出(高頻寫入)
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(System.out, StandardCharsets.UTF_8))) {
for (int i = 0; i < 10000; i++) {
bw.write("行號: " + i);
bw.newLine();
}
bw.flush(); // 確保寫入
}
// 錯誤輸出(重定向分離)
System.err.println("錯誤: 配置文件缺失");
| 問題 | 原因 | 解決 |
|---|---|---|
| 中文亂碼 | 編碼不匹配 | 顯式指定StandardCharsets.UTF_8 |
| readLine()返回null | 流關閉/EOF | 檢查null後再處理 |
| Scanner.nextInt()後nextLine()讀空行 | 換行符殘留 | 額外調用一次nextLine()消耗換行 |
| 控制台無法輸入 | IDE運行配置 | 勾選"Connect stdin"或使用終端運行 |
掌握BufferedReader + InputStreamReader組合可覆蓋90%控制台交互場景,Scanner適合結構化解析,字節流用於二進制/自定義協議處理。