1. 概述

本文将演示如何**将一个普通的 byte[] 转换为 InputStream**,先使用原生 Java 实现,再通过 Guava 库完成。这类操作在处理内存中的二进制数据(如文件缓存、网络响应体)时非常常见,属于 IO 处理的“基本功”。

本文是 Baeldung 系列教程 “Java – 回归基础” 的一部分,适合有一定 Java 开发经验的同学查漏补缺或作为速查笔记。

2. 使用原生 Java 转换

最简单粗暴的方式就是使用 JDK 自带的 ByteArrayInputStream —— 它本身就是 InputStream 的子类,构造时直接接收一个 byte[]

✅ 优点:无需额外依赖,性能好,语义清晰
❌ 缺点:功能单一,仅适用于内存数组

示例代码如下:

@Test
public void givenUsingPlainJava_whenConvertingByteArrayToInputStream_thenCorrect() 
    throws IOException {
    byte[] initialArray = { 0, 1, 2 };
    InputStream targetStream = new ByteArrayInputStream(initialArray);
    
    // 可以像普通流一样读取
    int data;
    while ((data = targetStream.read()) != -1) {
        System.out.print(data + " ");
    }
    // 输出: 0 1 2
}

⚠️ 注意:ByteArrayInputStream 不会真正“关闭”系统资源,调用 close() 通常是安全的但无实际作用,不过为了代码一致性建议仍加上 try-with-resources

3. 使用 Guava 转换

如果你的项目中已经引入了 Guava,可以考虑使用 ByteSource 工具类。它提供了更丰富的语义和链式操作能力,适合需要后续扩展的场景。

ByteSource.wrap(byte[]) 将字节数组包装成一个可复用的数据源,然后调用 openStream() 获取新的 InputStream 实例。

✅ 优点:API 更具表达力,支持缓存、复制、写入文件等扩展操作
❌ 缺点:需要引入第三方依赖

示例代码:

@Test
public void givenUsingGuava_whenConvertingByteArrayToInputStream_thenCorrect() 
    throws IOException {
    byte[] initialArray = { 0, 1, 2 };
    InputStream targetStream = ByteSource.wrap(initialArray).openStream();
    
    // 同样可以正常读取
    byte[] result = ByteStreams.toByteArray(targetStream);
    assertArrayEquals(initialArray, result);
}

📌 小贴士:ByteSource 是不可变的,每次 openStream() 都会返回一个新的 InputStream,非常适合需要多次读取同一数据源的场景(比如测试中反复使用 mock 数据)。


🔚 总结:

  • ✅ 日常开发优先使用 ByteArrayInputStream —— 简单高效
  • ✅ 若已在使用 Guava 且追求 API 一致性,ByteSource.wrap(...).openStream() 也是不错选择
  • ⚠️ 别忘了处理 IO 异常和资源释放,尤其是在封装工具方法时

原始标题:Java Byte Array to InputStream