【问题标题】:How to put the content of a ByteBuffer into an OutputStream?如何将 ByteBuffer 的内容放入 OutputStream?
【发布时间】:2010-10-09 10:32:48
【问题描述】:

我需要将java.nio.ByteBuffer 的内容放入java.io.OutputStream。 (希望我有一个Channel,但我没有)最好的方法是什么?

我不能使用 ByteBuffer 的 array() 方法,因为它可以是只读缓冲区。

我也可能在使用此 ByteBuffer 和拥有一个 byte[] 的常规数组之间散布对 OutputStream 的写入,我可以直接使用 OutputStream.write()

【问题讨论】:

    标签: java outputstream bytebuffer


    【解决方案1】:

    看看Channels.newChannel(OutputStream)。它会给你一个给定输出流的频道。使用 WritableByteChannel 适配器,您可以提供将其写入 OutputStream 的 ByteBuffer。

    public void writeBuffer(ByteBuffer buffer, OutputStream stream) {
       WritableByteChannel channel = Channels.newChannel(stream);
    
       channel.write(buffer);
    }
    

    这应该可以解决问题!

    【讨论】:

    • 如果我保留频道和流,我可以混合调用两者吗?
    • 是的,当然可以,减少每次创建频道的成本:)
    • 请注意,此方法涉及从 ByteBuffer 复制到临时数组,然后将其写入 OutputStream。如果性能很重要,您可能需要进行一些重构以避免不必要的块复制。
    • @trevor-robinson,你能扩展一下这个评论吗?为什么涉及副本?如何避免?
    • @Frederik, OutputStream 本身只接受字节数组,并且由于可能不支持ByteBuffer.array(),因此通常只能使用副本。作为一个特例,Oracle/OpenJDK Channels.newChannel impl 确实会检查流是否(完全)是 FileOutputStream,它有一个真正的本地通道;否则,它会返回一个适配器 (Channels.WritableByteChannelImpl),该适配器以最多 8KB 的块从缓冲区复制到一个数组。避免这种情况的唯一方法是始终使用渠道。您必须为 NIO 进行架构设计才能获得性能优势。
    猜你喜欢
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    相关资源
    最近更新 更多