Java ByteArrayOutputStream 用法详解

ByteArrayOutputStream 是 Java IO 中的字节数组输出流,核心作用是将数据写入到内存中的字节数组(内部维护可变字节缓冲区),最终可通过 toByteArray() 或 toString() 获取完整数据。它属于内存流(不涉及磁盘 IO),读写效率高,常用于临时存储字节数据、数据转换(如字符串→字节数组)、网络传输数据拼接等场景。

一、核心特性

  1. 内存存储:数据写入内存缓冲区,无需磁盘文件,速度快。
  2. 动态扩容:内部字节数组会根据写入数据量自动扩容(默认初始容量 1024 字节,满后按 2*当前容量+2 扩容)。
  3. 线程安全:所有 write 方法加了 synchronized 锁,支持多线程并发写入(但效率较低,单线程场景无需关注)。
  4. 无关闭成本:关闭后仍可继续使用(close() 方法为空实现),无需担心流关闭后无法写入。

二、常用构造方法

构造方法说明
ByteArrayOutputStream() 默认构造,初始缓冲区容量为 1024 字节
ByteArrayOutputStream(int size) 自定义初始容量(避免频繁扩容,提升效率)
 
示例:
 
// 默认容量(1024字节)
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();

// 自定义初始容量(适合已知大致数据大小的场景)
ByteArrayOutputStream baos2 = new ByteArrayOutputStream(2048);

 

三、核心方法(重点)

1. 写入数据:write() 系列

用于向内存缓冲区写入字节数据,有 3 种常用重载:
 
方法签名说明
write(int b) 写入单个字节(仅取 int 低 8 位,高 24 位忽略)
write(byte[] b) 写入整个字节数组
write(byte[] b, int off, int len) 写入字节数组的一部分(从 off 索引开始,写 len 个字节)
writeTo(OutputStream out) 将缓冲区所有数据写入到另一个输出流(如文件流、网络流)
 
示例:
 
ByteArrayOutputStream baos = new ByteArrayOutputStream();

// 1. 写入单个字节(ASCII 码对应字符:'A'→65, 'B'→66)
baos.write(65);
baos.write(66);

// 2. 写入整个字节数组
byte[] arr = "CDE".getBytes(); // 字符串转字节数组(默认编码UTF-8)
baos.write(arr);

// 3. 写入字节数组的一部分(从索引1开始,写2个字节:'E'、'F')
byte[] arr2 = "DEF".getBytes();
baos.write(arr2, 1, 2);

// 4. 写入到另一个输出流(如文件流)
try (FileOutputStream fos = new FileOutputStream("output.txt")) {
    baos.writeTo(fos); // 将缓冲区数据写入文件
} catch (IOException e) {
    e.printStackTrace();
}

 

 

2. 获取数据:toByteArray() / toString()

这是 ByteArrayOutputStream 最核心的用途 —— 获取写入的完整数据:
 
方法签名说明
byte[] toByteArray() 返回缓冲区的字节数组(拷贝一份新数组,修改不影响原缓冲区)
String toString() 用默认字符编码(如 UTF-8)将字节数组转为字符串
String toString(String charsetName) 用指定编码(如 "GBK")将字节数组转为字符串(推荐,避免编码乱码)
int size() 返回当前缓冲区中有效数据的长度(不是缓冲区容量)
 
示例:
 
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write("Hello, ".getBytes());
baos.write("ByteArrayOutputStream!".getBytes());

// 1. 获取字节数组
byte[] data = baos.toByteArray();
System.out.println("字节数组长度:" + data.length); // 输出:31

// 2. 转为字符串(默认编码)
String str1 = baos.toString();
System.out.println("默认编码字符串:" + str1); // 输出:Hello, ByteArrayOutputStream!

// 3. 转为字符串(指定编码,避免乱码)
String str2 = baos.toString("UTF-8");
System.out.println("UTF-8编码字符串:" + str2);

// 4. 获取有效数据长度
int length = baos.size();
System.out.println("有效数据长度:" + length); // 输出:31

 

 

3. 重置缓冲区:reset()

清空缓冲区中的数据,可重新写入(缓冲区容量不变,避免创建新对象,节省内存)。
 
示例: 
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write("测试数据".getBytes());
System.out.println("重置前:" + baos.toString()); // 输出:测试数据

baos.reset(); // 清空缓冲区
System.out.println("重置后长度:" + baos.size()); // 输出:0

baos.write("新数据".getBytes());
System.out.println("重置后写入:" + baos.toString()); // 输出:新数据

 

4. 关闭流:close()

ByteArrayOutputStream 的 close() 方法是空实现(源码中无任何操作),关闭后仍可正常写入和读取数据。
 
(注:Java IO 规范要求关闭流,但此处关闭无实际意义,仅为了符合 AutoCloseable 接口规范)
 
示例:
  
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.close(); // 关闭流(无效果)
baos.write("关闭后仍可写入".getBytes()); // 正常执行
System.out.println(baos.toString()); // 输出:关闭后仍可写入

posted @ 2025-11-20 16:47  都是城市惹的祸  阅读(21)  评论(0)    收藏  举报