有许多 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是OutputStreamand的内部 - 第三个是由我制作的副本,
toByteArray()所以我可以创建InputStream.
这种设计如何合理?
- 隐藏实现?只需提供
getInputStream(),实现保持隐藏。 - 多线程?
ByteArrayOutputStream无论如何都不适合多线程访问,所以这是不可能的。
此外,ByteArrayOutputStreamApache 的commons-io库(具有不同的内部实现)提供了第二种风格的 . 但是两者都具有完全相同的公共接口,不提供不复制就访问字节数组的方法。