Java中ByteArrayInputStream与ByteArrayOutputStream用法详解
在Java IO操作中,ByteArrayInputStream和ByteArrayOutputStream用于在内存中进行字节数据的读写。ByteArrayInputStream从字节数组中读取数据,支持跳过和标记重置功能;ByteArrayOutputStream则将数据写入可自动增长的缓冲区,并提供转换为字节数组或字符串的方法。本文通过实例代码演示其核心API的使用。
结果与目标
掌握如何使用ByteArrayInputStream从内存字节数组中读取数据,以及如何利用ByteArrayOutputStream将数据写入内存缓冲区,并实现两者之间的转换与复用。
准备条件
需要Java开发环境,确保引入java.io.ByteArrayInputStream和java.io.ByteArrayOutputStream类。以下示例基于ASCII码值对应的字节数据进行测试。
真实操作顺序
第1步:使用ByteArrayInputStream读取字节数组
目的:验证ByteArrayInputStream如何从指定字节数组中按顺序读取、跳过及重置位置。
入口:创建一个包含英文字母ASCII码的字节数组ArrayLetters,内容为“abcdefghijklmnopqrstuvwxyz”。
动作:
- 初始化流:将
ArrayLetters传入ByteArrayInputStream构造函数。 - 顺序读取:循环调用
bais.read()读取前5个字节(0x61至0x65)。 - 设置标记:调用
bais.mark(0)记录当前位置(即第6个字节0x66)。 - 跳过字节:调用
bais.skip(5)跳过5个字节,此时指针指向第11个字节(0x6B)。 - 批量读取:调用
bais.read(buf, 0, LEN)读取5个字节到数组buf中,结果为“klmno”。 - 重置流:调用
bais.reset()将指针回退至标记位置(0x66)。 - 再次读取:重新读取5个字节,结果为“fghij”。
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
public class ByteArrayInputStreamTest {
private static final int LEN = 5;
private static final byte[] ArrayLetters = {
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
};
public static void main(String[] args) {
tesByteArrayInputStream();
}
private static void tesByteArrayInputStream() {
ByteArrayInputStream bais = new ByteArrayInputStream(ArrayLetters);
// 读取前5个字节
for (int i=0; i<LEN; i++) {
if (bais.available() >= 0) {
System.out.printf("%d : 0x%s\n", i, Integer.toHexString(bais.read()));
}
}
// 支持mark/reset则继续
if (!bais.markSupported()) return;
bais.mark(0); // 标记当前位
bais.skip(5); // 跳过5位
byte[] buf = new byte[LEN];
bais.read(buf, 0, LEN); // 读取klmno
System.out.printf("str1=%s\n", new String(buf));
bais.reset(); // 重置标记位
bais.read(buf, 0, LEN); // 读取fghij
System.out.printf("str2=%s\n", new String(buf));
}
}
第2步:使用ByteArrayOutputStream写入数据
目的:演示如何将单个字节、部分数组写入ByteArrayOutputStream,并获取最终数据。
入口:创建空的ByteArrayOutputStream实例。
动作:
- 写入单个字节:连续调用
write()写入ASCII码0x41、0x42、0x43(对应ABC)。 - 写入数组片段:调用
baos.write(ArrayLetters, 3, 5),从索引3开始写入5个字节(defgh)。 - 获取长度:调用
size()确认总长度为8。 - 转换为字节数组:调用
toByteArray()获取完整字节内容,转为字符串显示为“ABCdefgh”。 - 输出到其他流:调用
writeTo()将数据写入另一个ByteArrayOutputStream副本。
import java.io.IOException;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
public class ByteArrayOutputStreamTest {
private static final int LEN = 5;
private static final byte[] ArrayLetters = {
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
};
public static void main(String[] args) {
tesByteArrayOutputStream();
}
private static void tesByteArrayOutputStream() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 写入ABC
baos.write(0x41);
baos.write(0x42);
baos.write(0x43);
System.out.printf("baos=%s\n", baos);
// 写入defgh
baos.write(ArrayLetters, 3, 5);
System.out.printf("baos=%s\n", baos);
// 获取大小和字节数组
System.out.printf("size=%s\n", baos.size());
byte[] buf = baos.toByteArray();
System.out.printf("str=%s\n", new String(buf));
// 复制到另一流
try {
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
baos.writeTo((OutputStream)baos2);
System.out.printf("baos2=%s\n", baos2);
} catch (IOException e) {
e.printStackTrace();
}
}
}
完成判断
运行上述代码后,控制台应分别输出正确的十六进制读取序列、重置后的字符串片段(str1=klmno, str2=fghij)以及输出流的累积内容(ABCdefgh),表明字节数组流的读写、跳转及转换功能正常。
简要总结
以上是对Java中ByteArrayInputStream与ByteArrayOutputStream用法的详细内容,更多关于Java IO流处理的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









