16

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

他们之间有什么不同?

4

3 回答 3

11

如果输入总是a byte[],那么你是对的,通常不需要流。如果您不需要它,请不要使用它。ByteArrayInputStream 的另一个优点是它非常强烈地表明您希望字节是只读的(因为流不提供更改它们的接口),但重要的是要注意程序员通常可以仍然直接访问字节,所以你不应该在担心安全的情况下使用它。

但是如果它有时是一个byte[],有时是一个文件,有时是一个网络连接等,那么你需要对“字节流,我不在乎它们来自哪里”进行某种抽象。这就是 InputStream。当源恰好是字节数组时,ByteArrayInputStream 是一个很好的 InputStream 使用。

这在许多情况下都有帮助,但举两个具体的例子:

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

    参考文档

  • 如果你选择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));
        }
    
于 2015-11-23T06:56:02.340 回答
1

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

于 2020-03-28T08:05:43.657 回答