ByteBuffer可以实现DataOutput/DataInput吗?

11

为什么java.nio.ByteBuffer没有实现java.io.DataOutputjava.io.DataInput,是因为某些微妙的原因,还是作者们没有选择这么做?将调用(如putInt() -> writeInt())映射似乎很简单。

我(以及一些其他人,显然)面临的基本问题是旧类已知如何使用通用接口DataInput / DataOutput对自身进行序列化/反序列化。我想重复使用自定义序列化而不编写自定义代理来代替ByteBuffer。

2个回答

5
只需使用put()wrap()方法,将缓冲区包装在ByteArrayInputStreamByteArrayOutputStream中即可。直接模拟datainput/output流的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,看起来很有趣。
- Justin
读取时的越界应该抛出EOFException;写入时的越界应该像写满卷一样处理(或者也可以抛出EOF)。 - Justin
@Justin:看了一下DataOutput的API,好像可以很好地工作。也许值得做一个小实验,确保你可以将DataOutput代理到一个干净的ByteBuffer上,并在oracle网站上发布一个bug或联系nio专家组。这两个API可能旨在面向不同级别的抽象;我不确定。 - andersoj
@Justin:这个对你也许会很有趣。http://mina.apache.org/iobuffer.html - andersoj
有关 InputStream 的情况,请参阅此相关问题:https://dev59.com/OW855IYBdhLWcg3wc0Dy - Raedwald
1
当foo没有这样的方法时,为什么要在其上调用close()?https://docs.oracle.com/javase/8/docs/api/java/io/DataOutput.html - user2163960

4
一种更好的方法,也适用于直接缓冲区:
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() 方法,然后才能从缓冲区读取数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接