Может ли ByteBuffer реализовать DataOutput / DataInput? - PullRequest
10 голосов
/ 01 ноября 2010

Есть ли какая-то скрытая причина, по которой java.nio.ByteBuffer не реализует java.io.DataOutput или java.io.DataInput или авторы просто не решили это делать? Казалось бы, просто отобразить вызовы (например, putInt () -> writeInt ()).

Основная проблема, с которой я (и некоторые другие , по-видимому), есть в старых классах, которые знают, как сериализовать / сериализовать себя, используя универсальные интерфейсы: DataInput / DataOutput. Я хотел бы повторно использовать мою пользовательскую сериализацию без написания собственного прокси для ByteBuffer.

Ответы [ 2 ]

4 голосов
/ 30 января 2011

Лучший способ, который работает и с прямыми буферами:

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 () после того, как вы закончите запись в него, прежде чем сможете читать из него.

4 голосов
/ 01 ноября 2010

Просто оберните буфер в ByteArrayInputStream или ByteArrayOutputStream, используя методы put() или wrap(). Проблема с прямой эмуляцией 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...
...