【问题标题】:java Presenting an InputStream as a ByteBuffer without loading the whole thing into an arrayjava将InputStream呈现为ByteBuffer而不将整个内容加载到数组中
【发布时间】:2016-07-06 20:15:18
【问题描述】:

我的应用程序获得了大量的大 InputStreams,并且需要将它们交给需要 ByteBuffers 的驱动程序。 Java InputStream to ByteBuffer 建议先转换成字节数组;但是,这很昂贵,并且确实破坏了使用 NIO 的全部意义。我正在寻找一种方法,让期望 ByteBuffer 的驱动程序可以根据需要从 InputStream 中读取数据。

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

【问题讨论】:

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

标签: java performance io


【解决方案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。您不应该害怕应用您在实践中链接的帖子。不会有性能损失。

    【讨论】:

      猜你喜欢
      • 2015-07-13
      • 2021-12-16
      • 1970-01-01
      • 2012-06-04
      • 1970-01-01
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多