为什么在 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 就像一个包装器,保护底层数组免受外部修改
- 具有高位读取、标记、跳过功能
流还有一个好处就是你不必同时把所有的字节都放在内存中,如果数据量很大的话很方便,可以很容易地在小块。
如果你选择 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 可以读取网络套接字、串行端口、蓝牙传输等。
据我了解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 就像一个包装器,保护底层数组免受外部修改
- 具有高位读取、标记、跳过功能
流还有一个好处就是你不必同时把所有的字节都放在内存中,如果数据量很大的话很方便,可以很容易地在小块。
如果你选择
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 可以读取网络套接字、串行端口、蓝牙传输等。