Запись гетерогенных типов в ByteBuffer
От: mbait  
Дата: 28.06.18 00:54
Оценка:
Есть абстрактная структура, которая коде представлена тремя переменными: long, int[], double[]. Каким образом правильнее всего записать данные в ByteBuffer? Проблема возникла из-за того, что такие методы как ByteBuffer::asDoubleBuffer() создают вид, которые при записи не обновляет position исходного буфера. Проще говоря, следующий код некорректен:

public void write(WritableChannel channel, long a, int[] b, double[] c) {
  ByteBuffer buffer = ByteBuffer.allocate(BIG_ENOUGH);
  buffer.putLong(a);
  buffer.asIntBuffer().put(b);    // не обновит buffer.position
  buffer.asDoubleBuffer().put(c)  // аналогично
  buffer.flip();                  // установит limit = 8
  channel.write(buffer);          // запишет только 'a'
}


Решения:
1. Можно вручную установить значение position вызовом ByteBuffer::position(int).
2. Можно использовать ByteBuffer::wrap(), оборачивая один и тот же byte[] со смещением:
byte[] buffer = new byte[BIG_ENOUGH];
ByteBuffer.wrap(buffer).putLong(a);
ByteBuffer.wrap(buffer, Long.BYTES, BIG_ENOUGH - Long.BYTES).asIntBuffer().put(b);
...


В последнем случае значение position нам неважно, потому что в конце мы вызовем:
channel.write(ByteBuffer.wrap(buffer))


Очевидно, что и так, и так можно допустить глупые ошибки, и вообще смысд использования ByteBuffer (и nio) пропадает. Как бы сделали вы?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.