本範例展示 Java I/O 體系的核心用法:BufferedReader、StringReader、DataInputStream、LineNumberReader、PrintWriter、DataOutputStream、隨機存取檔案等,串聯「讀取 -> 處理 -> 輸出」完整鏈路。
import java.io.*;
public class NewIODemo {
public static void main(String[] args) {
try {
// 1. 按行讀取檔案 (args[0] 為檔案路徑)
BufferedReader in = new BufferedReader(new FileReader(args[0]));
String s, s2 = "";
while ((s = in.readLine()) != null) s2 += s + "\n";
in.close();
// 1b. 讀取標準輸入
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter a line:");
System.out.println(stdin.readLine());
// 2. 從記憶體字串讀取 (StringReader)
StringReader in2 = new StringReader(s2);
int c;
while ((c = in2.read()) != -1) System.out.print((char)c);
// 3. 格式化記憶體輸入 (DataInputStream + 已棄用 StringBufferInputStream)
try {
DataInputStream in3 = new DataInputStream(new StringBufferInputStream(s2));
while (true) System.out.print((char)in3.readByte());
} catch (EOFException e) {
System.out.println("End of stream");
}
// 4. 行號輸出到檔案 (LineNumberReader + PrintWriter)
try {
LineNumberReader li = new LineNumberReader(new StringReader(s2));
BufferedReader in4 = new BufferedReader(li);
PrintWriter out1 = new PrintWriter(new BufferedWriter(new FileWriter("IODemo.out")));
while ((s = in4.readLine()) != null) {
out1.println("Line " + li.getLineNumber() + s);
}
out1.close();
} catch (EOFException e) {
System.out.println("End of stream");
}
// 5. 基本資料類型儲存與讀取 (DataOutputStream / DataInputStream)
try {
DataOutputStream out2 = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream("Data.txt")));
out2.writeDouble(3.14159);
out2.writeBytes("That was pi");
out2.close();
DataInputStream in5 = new DataInputStream(
new BufferedInputStream(new FileInputStream("Data.txt")));
BufferedReader in5br = new BufferedReader(new InputStreamReader(in5));
System.out.println(in5.readDouble()); // 讀回 double
System.out.println(in5br.readLine()); // 讀回字串
} catch (EOFException e) {
System.out.println("End of stream");
}
// 6. 隨機存取檔案 (RandomAccessFile) 此處省略
} catch (FileNotFoundException e) {
System.out.println("File Not Found: " + args[0]);
} catch (IOException e) {
System.out.println("IO Exception");
}
}
}
Java I/O 大量使用裝飾者模式動態組合功能:
FileReader (節點流) -> BufferedReader (緩衝) -> LineNumberReader (行號)FileOutputStream -> BufferedOutputStream -> DataOutputStream (基本型別寫入)| 場景 | 關鍵類 | 說明 |
|---|---|---|
| 高效行讀取 | BufferedReader.readLine() | 內部緩衝區減少系統調用,支援跨平台換行符 |
| 記憶體當檔案 | StringReader / StringWriter | 實現 CharSequence 與流介面互適配,單元測試常用 |
| 基本型別序列化 | DataInputStream / DataOutputStream | 機器無關二進制格式,適合資料檔而非文字檔 |
| 格式化文字輸出 | PrintWriter | 自動 flush、不拋 IOException、支援 printf 格式化 |
| 行號追蹤 | LineNumberReader | 裝飾 BufferedReader,getLineNumber() 獲取當前行號 |
| 標準輸入 | System.in -> InputStreamReader -> BufferedReader | 將位元組流轉字元流並緩衝 |
StringBufferInputStream、DataInputStream.readLine()(不正確處理字元集)。Files.readAllLines(Path)、Files.lines(Path) (Stream API)StandardCharsets.UTF_8 明確指定編碼try-with-resources 自動關閉資源 (Java 7+)RandomAccessFile 仍為隨機存取首選,或 FileChannel + MappedByteBuffer (NIO)try-with-resources 重構所有 close() 調用。DataOutputStream 與 ObjectOutputStream(序列化物件)差異。java.io 包源碼,理解 FilterInputStream 抽象裝飾基類。