ByteArrayOutputStream 是 Java 中高效动态合并字节数据的工具,基于可扩容 byte[] 实现,支持多源写入、自动扩容、复用重置,适用于协议组装等场景。

ByteArrayOutputStream 是 Java 中用于动态收集字节数据的高效工具,特别适合将多个字节源(如 byte[]、InputStream、字符串编码结果等)按需合并成一个连续字节数组。它内部基于可扩容的 byte[] 实现,无需预先知道总长度,避免手动计算和拼接开销。
基础合并:多个 byte[] 追加写入
最常见场景是把几个独立的字节数组按顺序合并。只需创建 ByteArrayOutputStream 实例,调用 write(byte[]) 多次即可:
- 每次 write() 都自动追加到内部缓冲区末尾
- 内部数组会自动扩容(默认增长 50%,也可通过构造函数指定初始容量)
- 调用 toByteArray() 获取最终合并结果(返回新数组,不共享内部缓冲区)
示例:byte[] a = "Hello".getBytes(); byte[] b = "World".getBytes(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(a); baos.write(b); byte[] merged = baos.toByteArray(); // 结果为 "HelloWorld" 的字节
混合来源:字节数组 + 字符串 + 流数据协同写入
ByteArrayOutputStream 支持多种输入形式,便于统一处理异构字节源:
- 字符串转字节:用 getBytes(StandardCharsets.UTF_8) 转换后 write()
- 从 InputStream 读取:可用 IOUtils.copy(inputStream, baos)(Apache Commons)或循环 read/write
- 单字节/小段数据:直接调用 write(int) 或 write(byte[], int, int)
注意:字符串编码必须显式指定(如 UTF-8),避免依赖平台默认编码导致乱码。
避免内存浪费:及时重用与释放
ByteArrayOutputStream 本身不持有外部资源,但其内部 byte[] 可能较大。若需多次合并操作,建议复用实例而非反复新建:
- 调用 reset() 清空当前内容并重置计数器,保留已分配的缓冲区空间
- 若后续数据量远小于当前容量,可调用 toByteArray() 后丢弃旧实例,让 GC 回收大数组
- 无需 close() —— 它不是基于系统资源的流,close() 仅标记为关闭,对功能无影响
替代方案对比:何时考虑其他方式
对于超大数据或高并发场景,ByteArrayOutputStream 可能受限于堆内存:
- 单次合并超过百 MB?考虑分块写入文件或使用 ByteBuffer 配合堆外内存
- 需要流式输出给网络或磁盘?可直接用 BufferedOutputStream 包装目标流,跳过内存中转
- 纯字符串拼接且无需二进制控制?StringBuilder 更轻量,但无法处理非文本字节
多数业务级合并(如协议头+体+签名、JSON 拼装、日志批量打包)用 ByteArrayOutputStream 简洁可靠。


















