设计ByteArrayOutputStream的公共接口的理由?

问题描述

| 在其公共API中有许多Java标准库和第三方库,其中有一些用于写入“ 0”或从中读取的方法一个示例是“ 1”,它花费“ 2”将已处理图像的内容写入其中。 另一个示例是iText pdf处理库,它需要ѭ2来将生成的pdf写入其中。 第三个示例是AmazonS3 Java API,它花费ѭ4,以便可以读取它并在S3存储中创建文件。 当您想将其中两个结合时,就会出现问题。例如,我有一个图像为
BufferedImage
,为此必须使用
ImageIO.write
将结果推入
OutputStream
。 但是没有直接的方法将其推送到Amazon S3,因为S3需要
InputStream
解决这个问题的方法很少,但是这个问题的主题是usage9的用法
ByteArrayOutputStream
的思想是使用包裹在
Input/Output Stream
中的中间字节数组,以便要写入输出流的家伙将写入数组,而要读取的家伙将读取该数组。 我想知道为什么“ 9”不允许不复制就访问字节数组,例如,提供“ 4”可以直接访问它。 访问它的唯一方法调用ѭ14,它将复制内部数组(标准数组)。这就是说,在我的图像示例中,我将在内存中拥有该图像的三个副本: 首先是实际的ѭ5 第二个是
OutputStream
的内部
array
, 第三是ѭ14制作的副本,因此我可以创建
InputStream
。 这种设计如何合理? 隐藏执行?只需提供20英镑,实现便会隐藏。 多线程?
ByteArrayOutputStream
仍然不适合多线程访问,因此不能。 而且,Apache的commons-io库(具有不同的内部实现)提供了“ 9”的第二种风味。 但是两者都具有完全相同的公共接口,不能提供不复制字节数组就可以访问的方法。     

解决方法

        幸运的是,内部数组是
protected
,因此您可以对其进行子类化,并在周围包裹
ByteArrayInputStream
,而无需进行任何复制。     ,我想知道为什么ByteArrayOutputStream不允许在不应对字节数组的情况下对其进行任何访问,例如,提供直接访问它的InputStream。 我可以想到四个原因: 当前的实现使用单个字节数组,但是也可以将其实现为字节数组的链接列表,从而将最终数组的创建推迟到应用程序要求时再进行。如果应用程序可以看到实际的字节缓冲区,则它必须是单个数组。 与您的理解相反,ѭ9是线程安全的,并且适合在多线程应用程序中使用。但是,如果提供了对字节数组的直接访问,则很难看到如何同步而不产生其他问题。 API将需要更加复杂,因为应用程序还需要知道当前缓冲区高水位线在哪里,以及字节数组是否(仍然)是活动字节数组。 (“ 9”实现有时需要重新分配字节数组...,这将使应用程序保留对不再是该数组的数组的引用。) 当公开字节数组时,您允许应用程序修改数组的内容,这可能会出现问题。   这种设计如何合理? 该设计是针对比您的使用案例更简单的用例量身定制的。 Java SE类库并非旨在支持所有可能的用例。但是它们不会阻止您(或第三方库)为其他用例提供其他流类。 最重要的是,Sun设计师决定不公开ѭ9的字节数组,并且(IMO)您不太可能改变主意。 (而且,如果您想尝试,那么这里不适合这样做。 尝试通过Bugs数据库提交RFE。 或开发一个添加功能的补丁,然后通过相关渠道将其提交给OpenJDK团队。如果您包括全面的单元测试和文档,则可能会增加机会。) 只要您可以提出不太危险的API设计,您就可以说服Apache Commons IO开发人员论证正确,取得更大的成功。 另外,也没有什么可以阻止您实施自己的专用版本来公开其内部数据结构的。该代码是GPL版本,因此您可以复制它...遵守关于代码分发的常规GPL规则。     ,        我认为您正在寻找的行为是管道。 ByteArrayOutputStream只是一个OutputStream,而不是一个输入/输出流。它不是为您的想法而设计的。