Разница между bytebuffer.flip() и bytebuffer.rewind()

Мне известно, что flip() устанавливает текущую позицию буфера в 0 и устанавливает предел для предыдущей позиции буфера, тогда как перемотка назад() просто устанавливает текущую позицию буфера на 0.

В следующем коде, либо я использую rewind() или flip(), я получаю тот же результат.

byte b = 127;
bb.put(b);
bb.rewind();//or flip();

System.out.println(bb.get());
bb.rewind();// or flip();
System.out.println(bb.get());

Не могли бы вы предоставить мне реальный пример, где разница в этих двух методах действительно имеет значение? Заранее спасибо. EDIT: Я нашел решение в этой ссылке, оно очень хорошо объяснено и подробно описано для полного понимания использования классов буфера и каналов.

Ответы

Ответ 1

Они вообще не эквивалентны.

A ByteBuffer обычно готов к read() (или для put()).

flip() делает его готовым для write() (или для get()).

rewind() и compact() и clear() снова запустите read()/put() после write() (или get()).

Ответ 2

Из исходного кода они очень похожи. Вы можете увидеть следующее:

public final Buffer flip() {
    limit = position;
    position = 0;
    mark = -1;
    return this;
}

public final Buffer rewind() {
    position = 0;
    mark = -1;
    return this;
}

Таким образом, значение flip устанавливается limit на position, а rewind - нет. Подумайте, что вы выделили буфер размером 8, вы заполнили буфер с 4 байтами, тогда позиция установлена ​​в 3, просто покажите, как следует:

    [ 1  1  1  1  0  0  0  0]
               |           |
flip           limit       |
rewind                     limit

Итак, rewind только что используемый предел установлен соответствующим образом.

Ответ 3

Метод rewind() похож на flip(), но не влияет на предел. Он только устанавливает позицию обратно на 0. Вы можете использовать функцию rewind(), чтобы вернуться назад и перечитать данные в уже перевернутом буфере. Общей ситуацией было бы следующее: после использования flip() вы читаете данные из буфера, вы хотите перечитать данные, этот метод будет работать.

Ответ 4

Вот пример, где два будут давать разные результаты. Как вы сказали, оба установлены в положение 0, разница между ними заключается в том, что флип устанавливает предел в предыдущую позицию.

Итак, с флип, если вы пишете (положите), предел для чтения (get) станет позицией последнего элемента, который вы написали. Если вы попытаетесь прочитать больше, чем это, он выдает исключение.

Перемотка оставляет предел неизменным. Предполагая, что он имеет емкость (размер буфера), он позволит вам продолжать чтение за пределами данных, которые вы на самом деле писали, в этом случае читая начальные нули, которые был инициализирован буфером.

ByteBuffer bb = ByteBuffer.allocateDirect(2);
byte b = 127;
bb.put(b);
bb.rewind();//or flip();

System.out.println(bb.get());  // will print 127 in either case
System.out.println(bb.get());  // will print 0 for rewind, BufferUnderflow exception for flip