java将InputStream呈现为ByteBuffer而不将整个内容加载到数组中
Posted
技术标签:
【中文标题】java将InputStream呈现为ByteBuffer而不将整个内容加载到数组中【英文标题】:java Presenting an InputStream as a ByteBuffer without loading the whole thing into an array 【发布时间】:2016-07-06 20:15:18 【问题描述】:我的应用程序获得了大量的大 InputStreams,并且需要将它们交给需要 ByteBuffers 的驱动程序。 Java InputStream to ByteBuffer 建议先转换成字节数组;但是,这很昂贵,并且确实破坏了使用 NIO 的全部意义。我正在寻找一种方法,让期望 ByteBuffer 的驱动程序可以根据需要从 InputStream 中读取数据。
在我正在处理的情况下,一次消耗整个 InputStream 并将其转换为数组太昂贵和浪费。
【问题讨论】:
这里的问题是驱动。它期望您将整个文件读入内存。糟糕的设计。 【参考方案1】:如果不先阅读整个InputStream
,您几乎无法做到这一点。
ByteBuffer
API 是随机访问,而InputStream
是严格顺序的。
此外,您不能创建自己的ByteBuffer
的子类,因为它的构造函数是包私有的并且java.nio
包是受限的。也就是说,您不能将InputStream
包装成ByteBuffer
;您必须使用ByteBuffer.wrap(byte[])
或ByteBuffer.allocateDirect()
。
【讨论】:
【参考方案2】:我认为这是不可能的。无论您是使用 ByteBuffer 还是只是从 InputStream 中读取,最终您都在使用由某人创建的字节数组。现在,当您将字节数组传递给 Buffer 时,Buffer 并没有初始化一个新的字节数组,它正在重用您实际传递的内容。此片段直接取自 Java 8 源代码,请自行查看:
ByteBuffer(int mark, int pos, int lim, int cap, // package-private
274 byte[] hb, int offset)
275
276 super(mark, pos, lim, cap);
277 this.hb = hb;
278 this.offset = offset;
279
正如您在上面的片段中看到的那样,ByteBuffer 直接使用字节数组,它不会再次处理它。因此,您已读取字节数组这一事实的惩罚为 0。您不应该害怕应用您在实践中链接的帖子。不会有性能损失。
【讨论】:
以上是关于java将InputStream呈现为ByteBuffer而不将整个内容加载到数组中的主要内容,如果未能解决你的问题,请参考以下文章
在 Java 中,如何将 InputStream 转换为字节数组 (byte[])? [复制]