byte[] bytes = new byte[1024*1024*10]; // 10MB 緩衝區
int len = -1;
StringBuffer buf = new StringBuffer();
while ((len = in.read(bytes)) != -1) {
buf.append(new String(bytes, 0, len));
}
文件內容 01234,為何輸出不是 001012012301234(累積歷史內容)?
read(byte[] b) 契約b.length 字節。b[0] ~ b[len-1],**不清理剩餘位置**。每次循環 in.read(bytes) 都會**覆蓋** bytes[0..len-1] 為最新讀取的數據。舊數據被新數據覆蓋,不再存在。new String(bytes, 0, len) 僅取本次有效區間,故無歷史殘留。
len < bytes.length 時若文件大小非緩衝區整數倍,最後一次 len 小於緩衝區大小。bytes[len...] 仍保留上次數據,**但 new String(bytes, 0, len) 截取長度為 len,舊數據不參與構造**,故安全。
文件: [0][1][2][3][4] (5字節)
緩衝區大小: 10 字節
第1次 read: len=5
bytes = [0][1][2][3][4][?][?][?][?][?]
new String(bytes,0,5) → "01234"
append → buf = "01234"
第2次 read: len=-1 (EOF) 循環結束
8KB~64KB 即可(4096 或 8192),10MB 過大易致 OOM。try-with-resources 自動關閉流(Java 7+)。Files.readAllLines 或 BufferedReader 逐行處理,避免手動編碼轉換。InputStream.read(byte[]) 每次**覆蓋緩衝區頭部**,len 标记有效長度。new String(bytes, 0, len) 精確截取本次有效數據,**不會累積歷史內容**。理解「緩衝區復用 + 長度截取」模式,是掌握 Java IO 流的關鍵。