Яка мета методу перевертання ByteBuffer? (А чому це називається "перевертати"?)


95

Чому метод flip () ByteBuffer називається "flip"? Що тут "перевернуто"? За словами apidoc, два послідовних перевертання не відновлять початковий стан, а багаторазові перевертання, ймовірно, limit()стануть нульовими.

Чи можу я якось "зняти", щоб повторно використовувати байти, які вийшли за межі?

Чи можу я зчепити хвіст для перегортання з деякими іншими даними?


5
Він "перевертає" буфер з читання на запис (і навпаки). Таким чином hw.blogspot.com/2009/10/…
Брайан Роуч

2
@BrianRoach: Це перемикається з прочитаного на запис, але це не так корисно для читання, якщо ви не пишете структури фіксованого розміру. Для перегортання для читання використовуйте resetзамість цього.
nneonneo

Не забувайте задавати «об’єктивні» запитання; або, принаймні, зробіть

@nneonneo - Це було якось не питанням, насправді не збирався витрачати багато часу на пояснення деталей, отже, лише коментар та посилання.
Брайан Роуч

Відповіді:


130

Одним з досить поширених випадків використання ByteBufferє побудова деякої структури даних поштучно, а потім запис цілої структури на диск. flipвикористовується для перемикання ByteBufferз "читання з вводу-виводу" ( putting) на "запис в I / O" ( getting): після того, як послідовність puts використовується для заповнення ByteBuffer, flipвстановить ліміт буфера в поточну позицію і скиньте положення на нуль. Це призводить до того, що майбутнє 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);
}

Що це за тип out?
Suzan Cioc

6
Або що-небудь ще, що має write(ByteBuffer)метод. (Це насправді не актуально, що це за тип ...)
Стівен С

1
Це повинно Buffer.clearскинути обмеження ємності та положення до 0. Buffer.resetскинути лише положення до mark.
Kelvin Ng

1
@KelvinNg: Ви маєте рацію; Я змінив відповідь, щоб відобразити це. Дякую за приємний улов!
nneonneo

1
@ user963241: читання з вводу-виводу в буфер, запис з буфера в введення-виведення.
nneonneo

7

Flip присвоює значення поточної позиції властивості limit і встановлює властивість position на 0. Flip корисний лише для зливу активних елементів з буфера.

Наприклад, нижче програма друкує "привіт" не порожні елементи буфера. Ліміт і позицію викликів методу можна замінити на перевертання.

CharBuffer cbuff = CharBuffer.allocate(40);
cbuff.put("hello"); 
// what below two line of code is what flip does
cbuff.limit(cbuff.position());
cbuff.position(0);      
while(cbuff.hasRemaining()) {
    System.out.println(cbuff.get());
}

Для отримання додаткової інформації про буфери та канали див. Http://www.zoftino.com/java-nio-tutorial .


Дякуємо за посилання на дуже широке висвітлення! Це так здорово, коли включаються джерела. Документи Java API, здавалося, використовували слово "перевертати" без пояснень, ніби це був загальноприйнятий термін інформатики, але очевидно, що кілька людей (включаючи мене) не виявили, що це так.
Джон Мейер,

3

ByteBuffer погано розроблений. Є багато скарг від пристойних програмістів.

Тому не намагайтеся міркувати про це, просто уважно вивчіть і використовуйте API.

Зараз я не можу згубити це, не представивши альтернативи, так ось:

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


6
Отже, які скарги? Якщо у вас є якась особиста скарга, це теж нормально, але це не означає просто сказати "X API відстій, люди так сказали".
nneonneo

13
Розміщення цього посилання - це буквально все, що вам потрібно було зробити в першу чергу. Я ніколи не звинувачував вас у брехні, я просто попросив вас детальніше пояснити джерело та характер скарг.
nneonneo

2
це просто місце, де люди пропонують свою допомогу добровільно, з належним зусиллям, яке вони вирішили. Мені не потрібно розширювати кожну відповідь у добре вивчену академічну роботу.
беззаперечний

8
і це також місце, де люди не вірять на чиєсь слово, якщо це не звучить достовірно.
arunmoezhi

8
Не потрібно навіть наводити джерела. Очевидно, що ByteBuffer погано розроблений. flip не заповнює мету, він просто вводить джерело помилок, коли ви забудете перевернути. Якщо вони відчули неконтрольоване бажання вкласти його, принаймні зробіть перевернуті та неперевернуті ByteBuffers різних класів, щоб система типів могла ловити помилки.
Gurgeh

0

Метод flip () робить буфер готовим до нової послідовності операцій запису каналу або відносного отримання: він встановлює ліміт на поточну позицію, а потім встановлює позицію на нуль.

Буфер відстежує дані, записані в нього. Для написання повідомлення використовується метод flip () для переключення з режиму запису на режим читання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.