構建一個互動式命令列工具,示範 Java 標準輸入(System.in)與標準輸出(System.out)的核心用法,包含緩衝讀取、指令解析、記憶體存儲與狀態機控制,適合作為 CLI 工具開發的起始範本。
in:內容:新增內容到記憶體向量out:列出所有已存內容quit:退出程式
import java.util.*;
import java.io.*;
public class StanderdIO {
public static void main(String[] args) {
Vector storage = new Vector<>();
boolean running = true;
// 建立緩衝讀取器包裝 System.in
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
while (running) {
System.out.print("input> ");
String line;
try {
line = stdin.readLine(); // 阻塞等待用戶輸入
} catch (IOException e) {
System.err.println("IO error: " + e.getMessage());
continue;
}
if (line == null) break; // EOF (Ctrl+D/Ctrl+Z)
// 解析指令:格式 "cmd:context" 或單純 "cmd"
String cmd = "", context = "";
int colon = line.indexOf(':');
if (colon == -1) cmd = line.trim();
else { cmd = line.substring(0, colon).trim(); context = line.substring(colon + 1); }
// 指令分發
switch (cmd.toLowerCase()) {
case "in":
if (context.isEmpty()) System.err.println("Error: 'in' requires content");
else storage.add(context);
break;
case "out":
for (int i = 0; i < storage.size(); i++)
System.out.println(i + ": " + storage.get(i));
break;
case "quit":
running = false;
break;
default:
System.err.println("Unknown command: " + cmd);
System.out.println("Usage: in:content | out | quit");
}
}
System.out.println("Bye!");
}
}
| 技術點 | 說明 |
|---|---|
System.in | 標準輸入流(通常連接鍵盤),類型為 InputStream |
InputStreamReader | 位元組流→字元流轉換器,指定編碼(預設平台編碼) |
BufferedReader | 緩衝字元讀取器,提供高效 readLine() 按行讀取 |
readLine() | 阻塞直到換行符或 EOF,返回不含換行符的字串,EOF 返回 null |
Vector | 執行緒安全的動態陣列,適合簡單單執行緒場景;現代代碼建議用 ArrayList |
java.io.Console 或 JLine 庫支援上下鍵翻歷史。System.in 是否為終端,非終端模式下批量處理管道輸入。Selector 或獨立執行緒實現即時互動。
// 使用 var 簡化聲明
var stdin = new BufferedReader(new InputStreamReader(System.in));
var storage = new ArrayList(); // 非執行緒安全場景優先 ArrayList
// 使用 switch expression (JDK 12+)
switch (cmd.toLowerCase()) {
case "in" -> { if (context.isEmpty()) err("'in' requires content"); else storage.add(context); }
case "out" -> storage.forEach((i, s) -> System.out.println(i + ": " + s));
case "quit" -> running = false;
default -> { err("Unknown: " + cmd); System.out.println("Usage: in:content | out | quit"); }
}