Разница между 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