| 增強功能 | 字節流裝飾者 | 字符流裝飾者 |
| 緩衝 (提升效能) | BufferedInputStream / BufferedOutputStream | BufferedReader / BufferedWriter |
| 基本類型讀寫 | DataInputStream / DataOutputStream | — (用 DataInput/OutputStream 配合轉換流) |
| 行號追蹤 | LineNumberInputStream (棄用) | LineNumberReader |
| 回退/預讀 | PushbackInputStream | PushbackReader |
| 格式化輸出 | PrintStream | PrintWriter |
經典組裝鏈
// 高效讀取文本文件 (按行)
BufferedReader in = new BufferedReader(
new InputStreamReader(
new FileInputStream("data.txt"), StandardCharsets.UTF_8));
// 高效寫入文本文件 (帶行號)
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("out.txt"), StandardCharsets.UTF_8)));
// 二進制數據持久化
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("data.bin")));
dos.writeDouble(3.14159);
dos.writeUTF("Hello");
RandomAccessFile —— 隨機訪問文件
- 模式:
"r" (只讀)、"rw" (讀寫)、"rws"/"rwd" (同步)。
- 核心方法:
seek(long pos) 定位、readXXX()/writeXXX() 讀寫基本類型、getFilePointer() 獲取當前指針。
- 適用場景:大文件斷點續傳、索引文件、嵌入式數據庫存儲引擎。
綜合實戰範例 (涵蓋讀寫、轉換、緩衝、格式化、隨機訪問)
import java.io.*;
public class IODemo {
public static void main(String[] args) throws IOException {
// 1. 按行讀取文件 → 字符串
StringBuilder content = new StringBuilder();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream("input.txt"), "UTF-8"))) {
String line;
while ((line = br.readLine()) != null) content.append(line).append('\n');
}
// 2. 從字符串讀取 (StringReader)
try (StringReader sr = new StringReader(content.toString())) {
int c;
while ((c = sr.read()) != -1) System.out.print((char)c);
}
// 3. 內存字節流 → DataInputStream 讀基本類型
try (DataInputStream dis = new DataInputStream(
new ByteArrayInputStream(content.toString().getBytes("UTF-8")))) {
while (true) System.out.print((char)dis.readByte());
} catch (EOFException ignored) { System.out.println("\n--- EOF ---"); }
// 4. 格式化寫入文件 (帶行號)
try (PrintWriter pw = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8")))) {
try (BufferedReader br = new BufferedReader(new StringReader(content.toString()))) {
String line; int n = 1;
while ((line = br.readLine()) != null) pw.println(n++ + ": " + line);
}
}
// 5. 數據存儲與恢復 (DataOutput/InputStream)
try (DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream("data.bin")))) {
dos.writeDouble(Math.PI);
dos.writeUTF("\nThis was pi: writeUTF");
dos.writeBytes("This was pi: writeBytes\n");
}
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(new FileInputStream("data.bin")))) {
System.out.println(dis.readDouble());
System.out.println(dis.readUTF());
System.out.println(dis.readUTF()); // readBytes 寫入的數據用 readUTF 讀會拋異常,此處僅示例
}
// 6. RandomAccessFile 隨機修改
try (RandomAccessFile raf = new RandomAccessFile("random.dat", "rw")) {
for (int i = 0; i < 10; i++) raf.writeDouble(i * 1.414);
raf.seek(5 * 8); // 定位到第 6 個 double
raf.writeDouble(47.0001); // 覆蓋
raf.seek(0);
for (int i = 0; i < 10; i++) System.out.println("Value " + i + ": " + raf.readDouble());
}
}
}
現代替代方案 (JDK 7+)
- NIO.2 (java.nio.file):
Files.readAllLines(), Files.write(), Files.newBufferedReader(),API 更簡潔、支援符號鏈接、屬性讀取。
- try-with-resources:自動關閉實現
AutoCloseable 的資源,消除 finally 樣板代碼。
- StandardCharsets:
StandardCharsets.UTF_8 替代字符串 "UTF-8",編譯期檢查拼寫。
總結
- 明確「字節 vs 字符」、「節點 vs 處理」二維分類,按需組裝流鏈。
- 緩衝 (
Buffered*) 是效能基石,幾乎所有文件讀寫都應加緩衝。
- 轉換流 必須顯式指定 Charset,杜絕平台相關亂碼。
- 隨機訪問用
RandomAccessFile;現代項目優先考慮 NIO.2 FileChannel + MappedByteBuffer。
- 資源管理統一使用
try-with-resources,簡潔且安全。
- 上一篇文章: Java 播放 MIDI 音樂的高效實現:複用 Sequencer 避免內存洩漏
- 下一篇文章: Java 垃圾收集算法深度解析:從核心思想到內存洩漏排查實戰
Copyright ©
程式碼之家 All Rights Reserved