java将InputStream表示为ByteBuffer,而不将整个内容加载到数组中

java将InputStream表示为ByteBuffer,而不将整个内容加载到数组中,java,performance,io,Java,Performance,Io,我的应用程序获得大量的大型输入流,需要将它们交给一个需要缓冲的驱动程序。建议首先将它们转换为字节数组;然而,这是昂贵的,而且确实破坏了使用NIO的全部意义。我正在寻找一种方法,使需要ByteBuffer的驱动程序可以根据需要从InputStream读取数据 在我正在处理的情况下,一次消耗整个InputStream并将其转换为一个数组既昂贵又浪费。我认为这是不可能的。无论您使用的是ByteBuffer还是仅仅从InputStream读取,最终您都使用的是由某人创建的字节数组。现在,当您将字节数组传

我的应用程序获得大量的大型输入流,需要将它们交给一个需要缓冲的驱动程序。建议首先将它们转换为字节数组;然而,这是昂贵的,而且确实破坏了使用NIO的全部意义。我正在寻找一种方法,使需要ByteBuffer的驱动程序可以根据需要从InputStream读取数据


在我正在处理的情况下,一次消耗整个InputStream并将其转换为一个数组既昂贵又浪费。

我认为这是不可能的。无论您使用的是ByteBuffer还是仅仅从InputStream读取,最终您都使用的是由某人创建的字节数组。现在,当您将字节数组传递到缓冲区时,缓冲区不是在初始化新的字节数组,而是在重用您实际传递的内容。此片段直接取自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直接使用字节数组,而不是再次处理它。因此,您读取字节数组的事实是零惩罚。你不应该害怕申请你在实践中链接的帖子。不会有性能损失。

如果不先阅读整个
输入流,您几乎无法做到这一点

ByteBuffer
API是随机访问,而
InputStream
是严格顺序的


此外,您不能创建自己的
ByteBuffer
子类,因为它的构造函数是包私有的,并且
java.nio
包受到限制。也就是说,不能将
输入流
包装到
字节缓冲区
;您必须使用
ByteBuffer.wrap(byte[])
ByteBuffer.allocateDirect()

这里的问题是驱动程序。它期望您将整个文件读入内存。糟糕的设计。