ByteArrayInputStream 與 ByteArrayOutputStream 將字節數組作為內存流來源/目的地,實現「內存↔流」零拷貝轉換,廣泛用於單元測試、序列化緩衝、圖片/文件內存處理。本文詳解兩大類核心 API 並附完整可運行示例。
byte[] buf 作為緩衝區。pos:下一個待讀字節索引;mark:標記位置;count:有效數據長度。InputStream,實現 read()、skip()、mark/reset 等標準接口。// 使用整個數組
ByteArrayInputStream(byte[] buf)
// 使用數組片段 offset/length
ByteArrayInputStream(byte[] buf, int offset, int length)
byte[] data = "abcdefghijklmnopqrstuvwxyz".getBytes();
ByteArrayInputStream bis = new ByteArrayInputStream(data);
// 1. 讀取前 5 字節
for (int i=0; i<5; i++) System.out.printf("%d: 0x%X%n", i, bis.read());
// 輸出: 0:61(a) 1:62(b) 2:63(c) 3:64(d) 4:65(e)
// 2. mark(0) 標記當前位置 (f)
bis.mark(0); // 參數 readlimit 在此類中無實際限制作用
// 3. skip(5) 跳過 5 字節 → 位置移至 k
bis.skip(5);
// 4. 讀取 5 字節到數組 → klmno
byte[] buf = new byte[5];
bis.read(buf, 0, 5);
System.out.println(new String(buf)); // klmno
// 5. reset() 回到 mark 位置 (f)
bis.reset();
// 6. 再讀 5 字節 → fghij
bis.read(buf, 0, 5);
System.out.println(new String(buf)); // fghij
read() 立即返回,無 I/O 等待。readlimit 參數被忽略。byte[] buf,初始 32 字節,寫入超過容量自動擴容(2倍)。count:當前有效字節數。OutputStream,實現 write()、toByteArray()、toString()、writeTo(OutputStream)。ByteArrayOutputStream bos = new ByteArrayOutputStream();
// 1. 寫入單字節 A/B/C (0x41/42/43)
bos.write(0x41); bos.write(0x42); bos.write(0x43);
System.out.println(bos); // ABC
// 2. 批量寫入數組片段 defgh (索引3長度5)
byte[] src = "abcdefghijklmnopqrstuvwxyz".getBytes();
bos.write(src, 3, 5);
System.out.println(bos); // ABCdefgh
// 3. 獲取長度與字節數組
int size = bos.size(); // 8
byte[] result = bos.toByteArray(); // [65,66,67,100,101,102,103,104]
// 4. 輸出到另一個流
ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
bos.writeTo(bos2);
System.out.println(bos2); // ABCdefgh
toString(StandardCharsets.UTF_8)(Java 9+)或 new String(buf, 0, count, "UTF-8")。close() 空實現,不釋放內存,GC 回收數組。ByteArrayInputStream。| 場景 | 用法 |
|---|---|
| 單元測試 Mock 流 | new ByteArrayInputStream(json.getBytes()) 模擬網絡響應 |
| 序列化緩衝 | 對象 → ByteArrayOutputStream → byte[] → Redis/DB |
| 圖片內存處理 | 讀取文件 → ByteArrayInputStream → ImageIO.read → 處理 → ByteArrayOutputStream → 上傳 |
| 壓縮/加密中間緩衝 | GZIPOutputStream 包裝 ByteArrayOutputStream 直接壓縮到內存 |
| 日誌/指標聚合 | 多線程寫入各自 ByteArrayOutputStream,定期合併刷盤 |
toString("UTF-8") 避免跨平台亂碼。null,助 GC 回收大數組。ByteArrayOutputStream 時加鎖或用 ThreadLocal 隔離。ByteArrayInputStream 讓字節數組具備流讀取能力,ByteArrayOutputStream 讓流輸出聚合為字節數組。兩者配合實現「內存流」閉環,是 Java IO 體系中輕量級、高性能的內存數據交換基石。