【问题标题】:Java InputStream to ByteBufferJava InputStream 到 ByteBuffer
【发布时间】:2015-07-13 14:21:54
【问题描述】:

我正在阅读 dds 纹理,但是自从构建了 jar 后,我无法通过 urlfile 访问这些纹理,而必须使用 InputStream

所以我需要知道如何从java.io.InputStream 获取java.​nio.ByteBuffer

Ps:无论通过第三部分库,我只需要它工作

【问题讨论】:

    标签: java inputstream bytebuffer


    【解决方案1】:

    对我来说,在这种情况下最好是 Apache commons-io 来处理这个和类似的任务。

    IOUtils 类型有一个静态方法来读取 InputStream 并返回 byte[]

    InputStream is;
    byte[] bytes = IOUtils.toByteArray(is);
    

    这会在内部创建一个ByteArrayOutputStream 并将字节复制到输出,然后调用toByteArray()

    更新:只要你有byte array,正如@Peter所指出的,你必须转换为ByteBuffer

    ByteBuffer.wrap(bytes)
    

    JAVA 9 更新:如 @saka1029 所述,如果您使用的是 java 9+,则可以使用默认的 InputStream API,该 API 现在包含 InputStream::readAllBytes 函数,因此不需要外部库

    InputStream is;
    byte[] bytes = is.readAllBytes()
    

    【讨论】:

    • 然后到ByteBuffer?
    • @elect 是,ByteBuffer.wrap(bytes)
    • 可能内存不足
    • @chen 它可能会OOM。此方法仅适用于小文件。这就是为什么人们发明 InputStream API :-) >> 以流的形式读取某些内容(一段接一段)。
    【解决方案2】:

    不需要 3rd 方库的简洁解决方案是

    ByteBuffer byteBuffer = ByteBuffer.allocate(inputStream.available());
    Channels.newChannel(inputStream).read(byteBuffer);
    

    ReadableByteChannel#read(ByteBuffer)

    【讨论】:

    • 你确定一个read()足以读取所有输入流吗?
    • 不,这取决于您使用的InputStream。如果它有所有可用的字节,那么它将工作。
    【解决方案3】:

    关于:

    ReadableByteChannel channel = Channels.newChannel(inputStream);
    ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
    
    while (channel.read(buffer) != -1) {
      //write buffer
    
    };
    

    【讨论】:

    • 您确定read() 在输入流结束时返回-1 吗?有时它会返回 0。
    • 是的,我是 %)) 这是来自 ReadableByteChannel 的 javadoc Returns: The number of bytes read, possibly zero, or -1 if the channel has reached end-of-stream
    • 如果缓冲区不够大,无法读取整个输入流,这可能会卡在一个繁忙的循环中,试图一遍又一遍地读取 0 字节。取决于循环体如何处理缓冲区。例如如果您只想将所有内容读入缓冲区并返回缓冲区,则缓冲区不会在循环中被清空或翻转。
    猜你喜欢
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 1970-01-01
    • 2014-11-11
    • 1970-01-01
    • 2017-08-31
    相关资源
    最近更新 更多