有许多 java 标准和 3rd 方库,在它们的公共 API 中,有写入或读取Stream
. 一个例子是javax.imageio.ImageIO.write()
将OutputStream
处理过的图像的内容写入其中。另一个例子是iText pdf 处理库,它将OutputStream
生成的 pdf 写入其中。第三个示例是 AmazonS3 Java API,InputStream
它将读取它并在S3 存储中创建文件。
当您想将其中两个结合起来时,就会出现问题。例如,我有一个图像BufferedImage
,我必须使用它ImageIO.write
来将结果推送到OutputStream
. 但是没有直接的方法将它推送到 Amazon S3,因为 S3 需要InputStream
.
解决这个问题的方法很少,但这个问题的主题是ByteArrayOutputStream
.
背后的想法ByteArrayOutputStream
是使用包装的中间字节数组,Input/Output Stream
以便想要写入输出流的人将写入数组,而想要读取的人将读取数组。
我想知道为什么ByteArrayOutputStream
不允许在不复制字节数组的情况下对其进行任何访问,例如,提供一个InputStream
可以直接访问它的字节数组。访问它的唯一方法是调用toByteArray()
,这将复制内部数组(标准数组)。这意味着,在我的图像示例中,我将在内存中保存三个图像副本:
- 首先是实际的
BufferedImage
, - 其次
array
是OutputStream
and的内部 - 第三个是由我制作的副本,
toByteArray()
所以我可以创建InputStream
.
这种设计如何合理?
- 隐藏实现?只需提供
getInputStream()
,实现保持隐藏。 - 多线程?
ByteArrayOutputStream
无论如何都不适合多线程访问,所以这是不可能的。
此外,ByteArrayOutputStream
Apache 的commons-io库(具有不同的内部实现)提供了第二种风格的 . 但是两者都具有完全相同的公共接口,不提供不复制就访问字节数组的方法。