Какова цель метода ByteBuffer flip? (И почему он называется "флип"?)

Почему метод ByteBuffer flip() называется "flip"? Что здесь "перевернулось"? Согласно apidoc, два последовательных флипса не будут восстанавливать исходное состояние, а несколько флип, вероятно, будут стремиться limit() к нулю.

Можно ли "unflip" каким-то образом повторно использовать байты, выходящие за пределы?

Могу ли я конкатенировать хвост, который нужно перевернуть с некоторыми другими данными?

Ответ 1

Один довольно распространенный вариант использования для ByteBuffer - это построение некоторой структуры данных по частям, а затем запись всей структуры на диск. flip используется для перевода ByteBuffer с "чтения с ввода-вывода" (put ting) на "запись в I/O" (get ting): после того, как последовательность put используется для заполните ByteBuffer, flip установите предел буфера на текущую позицию и reset позицию на ноль. Это приводит к тому, что из буфера будущие get или write пишут все, что было put, в буфер и не более.

После завершения put вы можете повторно использовать ByteBuffer для построения другой структуры данных. Чтобы "разблокировать" его, вызовите clear. Это сбрасывает ограничение на емкость (делая весь используемый буфер), а положение равно 0.

Итак, типичный сценарий использования:

ByteBuffer b = new ByteBuffer(1024);
for(int i=0; i<N; i++) {
    b.clear();
    b.put(header[i]);
    b.put(data[i]);
    b.flip();
    out.write(b);
}

Ответ 2

ByteBuffer плохо разработан. Есть много жалоб от достойных программистов.

Поэтому не пытайтесь рассуждать об этом, просто изучите и используйте API.

Теперь я не могу использовать его, не представляя альтернативы, так вот:

Буфер имеет фиксированный capacity; он поддерживает 2 указателя: start и end. get() возвращает байт в позиции start и увеличивает start. put() помещает байт в позицию end и увеличивает end. Нет flip()!