为什么在 Java 中使用 ByteArrayInputStream 而不是 byte[]

Why to use ByteArrayInputStream rather than byte[] in Java

据我了解ByteArrayInputStream用于读取byte[]数据。 为什么我应该使用它而不是简单的 byte[] (例如从数据库中读取它)。

它们有什么区别?

如果输入是 always a byte[],那么你是对的,通常不需要流。并且 if you don't need it, don't use it。 ByteArrayInputStream 的另一个优点是它可以作为一个非常强烈的指示,表明您希望字节是只读的(因为流不提供用于更改它们的接口),尽管重要的是要注意程序员 can 通常仍然直接访问字节,因此您不应该在担心安全问题的情况下使用它。

但如果它有时是 byte[]、有时是文件、有时是网络连接等,那么您需要对 "a stream of bytes, and I don't care where they come from." 进行某种抽象,这就是 InputStream。当源恰好是字节数组时,ByteArrayInputStream 是一个很好用的 InputStream。

这在很多情况下都有用,但举两个具体的例子:

  • 您正在编写一个接受字节并以某种方式处理它们的库(例如,它可能是一个图像处理库)。您的库的用户可能会从文件、内存中的 byte[] 或其他来源提供字节。因此,您提供了一个接受 InputStream 的接口——这意味着如果他们拥有的是 byte[],他们需要将其包装在 ByteArrayInputStream 中。
  • 您正在编写读取网络连接的代码。但是要对该代码进行单元测试,您不希望必须打开一个连接;您只想在代码中提供一些字节。因此代码采用 InputStream,而您的测试提供 ByteArrayInputStream。
  • 一个 ByteArrayInputStream 包含一个内部缓冲区,其中包含的字节 可以从流中读取。 内部计数器跟踪读取方法提供的下一个字节。
  • ByteArrayInputStream 就像一个包装器,保护底层数组免受外部修改
  • 具有高位读取、标记、跳过功能
  • 流还有一个好处就是你不必同时把所有的字节都放在内存中,如果数据量很大的话很方便,可以很容易地在小块。

    Reference doc

  • 如果你选择 byte[] ,那么你必须 生成轮子来明确地读取、跳过和跟踪当前索引

    byte data[] = { 65, 66, 67, 68, 69 }; // data
        for (int index = 0; index < data.length; index++) {
            System.out.print((char) data[index] + "   ");
        }
        int c = 0;
        ByteArrayInputStream bInput = new ByteArrayInputStream(data);
        while ((bInput.read()) != -1) {
            System.out.println(Character.toUpperCase((char) c));
        }
    

ByteArrayInputStream 是 byte[] 的一个很好的包装器,核心是理解流,流是不确定的字节的有序序列 length.Input 流将数据字节移动到一个 java 来自一些一般外部源的程序,在 java io 中,您可以将一个流装饰为另一个流以获得更多功能。但性能可能很差。流隐喻的强大之处在于,这些源和目标之间的区别是抽象的方式,所有输入和输出操作都使用相同的 class 和相同的方法简单地作为流进行交易,你不需要学习新的 API 对于每一种不同类型的设备,读取文件的相同 API 可以读取网络套接字、串行端口、蓝牙传输等。