Java IO 採用裝飾器模式構建靈活的流管道。不同於其他語言的「一行代碼讀文件」,Java 需組合多個流對象,但獲得了極大的靈活性:可自由組合「數據源 → 轉換 → 緩衝 → 格式化」等功能層。
| 基類 | 方向 | 數據類型 | 典型子類 |
|---|---|---|---|
| InputStream | 讀 | 字節 | FileInputStream, ByteArrayInputStream, GZIPInputStream |
| OutputStream | 寫 | 字節 | FileOutputStream, ByteArrayOutputStream, GZIPOutputStream |
| Reader | 讀 | 字符 (Unicode) | FileReader, BufferedReader, InputStreamReader |
| Writer | 寫 | 字符 (Unicode) | FileWriter, BufferedWriter, OutputStreamWriter |
| 裝飾器 | 包裝目標 | 功能 |
|---|---|---|
| BufferedInputStream/Reader | InputStream/Reader | 緩衝讀取,減少系統調用 |
| BufferedOutputStream/Writer | OutputStream/Writer | 緩衝寫入,批量刷新 |
| InputStreamReader | InputStream | 字節流 → 字符流 (指定編碼) |
| OutputStreamWriter | OutputStream | 字符流 → 字節流 (指定編碼) |
| DataInputStream/DataOutputStream | InputStream/OutputStream | 基本類型讀寫 (int, double 等) |
| ObjectInputStream/ObjectOutputStream | InputStream/OutputStream | 對象序列化/反序列化 |
| GZIPInputStream/GZIPOutputStream | InputStream/OutputStream | 壓縮/解壓 |
| LineNumberReader | Reader | 行號追蹤 |
| PushbackInputStream/Reader | InputStream/Reader | 回退/預讀 |
// 現代寫法 (Java 7+ try-with-resources)
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream("file.txt"), StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
層次:FileInputStream(字節源) → InputStreamReader(解碼) → BufferedReader(緩衝+按行讀取)
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("out.txt"), StandardCharsets.UTF_8))) {
bw.write("Hello World");
bw.newLine();
bw.write("你好世界");
}
try (FileInputStream in = new FileInputStream("src.dat");
FileOutputStream out = new FileOutputStream("dest.dat")) {
byte[] buffer = new byte[8192];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}
try (DataInputStream dis = new DataInputStream(
new GZIPInputStream(
new FileInputStream("data.gz")))) {
int value = dis.readInt();
double d = dis.readDouble();
}
層次:FileInputStream → GZIPInputStream(解壓) → DataInputStream(基本類型讀取)
StandardCharsets.UTF_8
// 底層高效複製,native 實現 (memmove)
System.arraycopy(src, srcPos, dest, destPos, length);
// 包裝層,創建新數組並複製
Arrays.copyOf(original, newLength);
IO 內部大量使用 System.arraycopy 進行緩衝區管理。
// Java 7+ try-with-resources 自動關閉 (實現 AutoCloseable)
try (Resource r1 = ...; Resource r2 = ...) {
// 使用資源
} catch (IOException e) {
// 處理異常
}
// 無需 finally 手動 close,即使異常也會關閉
// Files 工具類:一行代碼完成常見操作
List lines = Files.readAllLines(Paths.get("file.txt"), StandardCharsets.UTF_8);
Files.write(Paths.get("out.txt"), lines, StandardCharsets.UTF_8);
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);
Files.move(src, dest);
Files.delete(path);
Stream lines = Files.lines(Paths.get("big.txt")); // 流式處理大文件
class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private transient String password; // 不序列化
// ...
}
// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
oos.writeObject(user);
}
// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
User u = (User) ois.readObject();
}
Java IO 通過四大基類和豐富的裝飾器,構建了功能強大、組合靈活的流體系。核心掌握點:
理解裝飾器模式在 IO 中的應用,不僅能熟練使用 Java IO,更能領會「組合優於繼承」的設計智慧。