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 jvm之直接内存释放过程

在 Java 中,如何将 InputStream 转换为字节数组 (byte[])? [复制]

java 将inputstream转换为字符串

java 将InputStream转换为字节数组

将 int 转换为字节 - Java 和 Actionscript 中的不同结果

java 用于将InputStream转换为String的实用程序函数。