Java 提供多種從標準輸入讀取數據的方式,適用場景各異。本文對比三種主流方法的特點、代碼模板與優缺點。
| 方式 | 核心類/方法 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|---|
| 原始字節流 | System.in.read() | 單字符/字節讀取、底層調試 | 無依賴、最基礎 | 僅讀單字節、需手動組裝字符串、異常處理繁瑣 |
| 掃描器 | java.util.Scanner | 結構化輸入(數字、單詞、行)、簡單交互 | 自動分詞、內置類型轉換、正則分隔符 | 性能一般、緩衝區較小、大數據量較慢 |
| 緩衝字符流 | BufferedReader + InputStreamReader | 整行讀取、高性能文本處理、包含空格的輸入 | 高效緩衝、按行讀取、支持任意字符集 | 需手動轉換類型、代碼稍多 |
// 讀取單字節 (返回 int, -1 表示 EOF) int b = System.in.read(); // 讀取多字節到 byte[] byte[] buf = new byte[1024]; int len = System.in.read(buf); // 阻塞直到有數據或 EOF String str = new String(buf, 0, len, StandardCharsets.UTF_8);
⚠️ 實際項目極少直接使用,通常作為其他流的構造參數。
import java.util.Scanner;
Scanner sc = new Scanner(System.in); // 默認分隔符:空白字符 (空格、Tab、換行)
System.out.print("輸入整數 n: ");
int n = sc.nextInt(); // 讀取下一個 token 並轉 int
String word = sc.next(); // 讀取下一個單詞
String line = sc.nextLine(); // 讀取整行 (含空格)
double d = sc.nextDouble(); // 讀取浮點數
boolean flag = sc.nextBoolean(); // 讀取布爾值
// 完整示例:讀取一行包含空格的字符串並分割為整數數組
System.out.print("輸入數組 (空格分隔): ");
String line = sc.nextLine();
String[] parts = line.split("\\s+");
int[] arr = new int[parts.length];
for (int i = 0; i < parts.length; i++) arr[i] = Integer.parseInt(parts[i]);
關鍵點:nextLine() 讀取剩餘行內容(含前導空白),next()/nextInt() 跳過前導分隔符讀取下一 token。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
System.out.print("輸入一行文本: ");
String line = br.readLine(); // 讀取整行,不含換行符,EOF 返回 null
// 讀取多行直到 "exit"
String input;
while ((input = br.readLine()) != null) {
if ("exit".equalsIgnoreCase(input)) break;
System.out.println("Echo: " + input);
}
// 解析空格分隔整數
String[] nums = line.split("\\s+");
int[] arr = Arrays.stream(nums).mapToInt(Integer::parseInt).toArray();
優勢:默認 8KB 緩衝區,適合大文件/高頻讀取;readLine() 保留行內所有空格,解析更靈活。
Scanner 寫法最簡潔,或用 BufferedReader + split 追求極致速度Scanner 直接支持類型轉換,體驗最好BufferedReader 批量讀取、流式處理try-with-resources 自動關閉 Scanner/BufferedReaderStandardCharsets.UTF_8 或 Charset.defaultCharset()// System.in 非線程安全,多線程讀取會交錯
// 方案:單線程讀取分發,或使用 java.io.Console (Java 6+)
Console console = System.console();
if (console != null) {
String pwd = new String(console.readPassword("Password: ")); // 不回顯
String line = console.readLine("Input: ");
}
Console 結合讀取與密碼掩碼,但IDE 運行時可能為 null(需真終端)。