字符流本質:字節流 + 解碼器。讀取二進制數據,按指定編碼(默認平台編碼)解碼為字符;寫入時編碼為字節。核心關係:字符流 = 字節流 + 解碼/編碼。
Reader 為抽象基類,FileReader 為文件字符輸入流實現。
File 對象)new FileReader(file))read(char[]) 返回實際讀取字符數)FileReader frd = new FileReader(file);
int content;
while ((content = frd.read()) != -1) {
System.out.print((char) content); // 極慢,每次調用 native 方法
}
frd.close();
FileReader frd = new FileReader(file);
char[] buffer = new char[1024];
int len;
while ((len = frd.read(buffer)) != -1) {
System.out.println(new String(buffer, 0, len)); // 按實際長度構造字符串
}
frd.close();
Writer 為抽象基類,FileWriter 為文件字符輸出流實現。
FileWriter 內部維護 1024 字符緩衝區,數據先寫入緩衝區,滿或 flush()/close() 時才刷盤new FileWriter(file, true) 第二參數 true 開啟追加File file = new File("D:\\a.txt");
FileWriter fwt = new FileWriter(file, true); // 追加模式
fwt.write("持續授課");
fwt.close(); // 隱含 flush()
// 錯誤示範:字符流複製二進制文件
FileReader frd = new FileReader(src);
FileWriter fwt = new FileWriter(dest);
char[] ch = new char[1024];
int len;
while ((len = frd.read(ch)) != -1) {
fwt.write(ch, 0, len);
fwt.flush();
}
失敗原因:
| 場景 | 推薦流類型 | 理由 |
|---|---|---|
| 圖片、視頻、音頻、壓縮包等二進制文件 | 字節流(InputStream/OutputStream) | 無需解碼,直接操作字節,保證數據完整性 |
| 文本文件、XML、JSON、CSV、屬性配置等 | 字符流(Reader/Writer) | 需按編碼解碼為字符,便於文本處理 |
| 網絡傳輸、序列化、隨機訪問文件 | 字節流 | 底層協議基於字節,字符流會引入額外編碼開銷 |
無論字節流還是字符流,生產代碼務必包裝緩衝流:
// 字符流緩衝
BufferedReader br = new BufferedReader(new FileReader(file));
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
// 字節流緩衝
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
緩衝流大幅減少系統調用次數,是 IO 效能優化的第一步。