ByteBuffer 可以实现 DataOutput/DataInput 吗?

Posted

技术标签:

【中文标题】ByteBuffer 可以实现 DataOutput/DataInput 吗?【英文标题】:Could ByteBuffer implement DataOutput/DataInput? 【发布时间】:2010-11-01 18:44:07 【问题描述】:

java.nio.ByteBuffer 没有实现java.io.DataOutput 或java.io.DataInput 是否有一些微妙的原因,或者作者只是没有选择这样做?映射调用似乎很简单(例如 putInt() -> writeInt())。

我(显然还有一些others)遇到的基本问题是知道如何使用通用接口对自己进行序列化/序列化的旧类:DataInput/DataOutput。我想重用我的自定义序列化而不为 ByteBuffer 编写自定义代理。

【问题讨论】:

【参考方案1】:

只需使用put()wrap() 方法将缓冲区包装在ByteArrayInputStreamByteArrayOutputStream 中。让ByteBuffer 直接模拟数据输入/输出流的问题与事先不知道大小有关。万一超车怎么办?

需要的是一个ByteBufferOutputStream,您可以在其中包装/公开所需的行为。存在这样的例子; Apache avro 序列化方案有这样的东西。自己动手并不难。为什么默认没有一个?好吧,这不是一个完美的世界......

ByteArrayOutputStream backing = new ByteArrayOutputStream();
DataOutput foo = new DataOutputStream(backing); 
// do your serialization out to foo

foo.close();
ByteBuffer buffer = ByteBuffer.wrap(backing.toByteArray());
// now you've got a bytebuffer...

【讨论】:

+ 提到了 Avero,看起来很有趣。 读取时溢出应该抛出 EOFException;写入溢出将被视为写入完整卷(或者也只是抛出 EOF) @Justin:看看DataOutput api,是的,这可能工作得很好。也许值得做一个小实验,以确保您可以干净地将DataOutput 代理到ByteBuffer 并在 oracle 站点上发布错误或联系 nio 专家组。可能这两个 api 旨在针对不同的抽象级别;我不确定。 @Justin:这对你来说可能也很有趣。 mina.apache.org/iobuffer.html 当 foo 没有这样的方法时,你为什么要在 foo 上调用 close()? docs.oracle.com/javase/8/docs/api/java/io/DataOutput.html【参考方案2】:

也可以使用直接缓冲区的更好方法:

class ByteBufferOutputStream extends OutputStream

    private final ByteBuffer buffer;

    public ByteBufferOutputStream(ByteBuffer buffer)
    
        this.buffer = buffer;
    

    public void write(int b) throws IOException
    
        buffer.put((byte) b);
    

请注意,这需要在完成写入后调用 buffer.flip(),然后才能从中读取。

【讨论】:

以上是关于ByteBuffer 可以实现 DataOutput/DataInput 吗?的主要内容,如果未能解决你的问题,请参考以下文章

ByteBuffer 介绍及 C++ 实现

ByteBuffer 介绍及 C++ 实现

可以扩展通过 allocateDirect 方法创建的 ByteBuffer 吗?

ByteBuffer 的 Xamarin 实现。弄错了吗?

Java:转换 ByteBuffer 多维数组

ByteBuffer说明