Какова цель метода переворота ByteBuffer? (И почему это называется «переворот»?)


95

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

Могу ли я как-нибудь "развернуть", чтобы повторно использовать байты, вышедшие за предел?

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


5
Он «переворачивает» буфер с чтения на запись (и наоборот). thushw.blogspot.com/2009/10/…
Брайан Роуч

2
@BrianRoach: он переключается с чтения на запись, но не так полезен для записи на чтение, если вы не пишете структуры фиксированного размера. Для перелистывания, чтобы писать для чтения, используйте resetвместо этого.
nneonneo

Не забывайте задавать «объективные» вопросы; или, по крайней мере, сделать преобладающий вопрос объективным: D

@nneonneo - Это не было вопросом, на самом деле я не собирался тратить много времени на объяснение деталей, поэтому просто комментарий и ссылка.
Брайан Роуч

Ответы:


130

Один довольно распространенный вариант использования ByteBuffer- это построение некоторой структуры данных по частям, а затем запись всей этой структуры на диск. flipиспользуется для переключения ByteBufferот «чтения из ввода / вывода» ( putting) к «записи в ввод / вывод» ( 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.
Кельвин Нг,

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 для получения дополнительной информации о буферах и каналах.


Спасибо за ссылку на очень обширное освещение! Это так здорово, когда включены исходники. В документах API Java, казалось, использовалось слово «перевернуть» без объяснения, как если бы это был общий термин в информатике, но, очевидно, некоторые люди (включая меня) не обнаружили, что это так.
Джон Мейер

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 05

0

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

Buffer отслеживает записанные в него данные. После записи вызывается метод flip () для переключения из режима записи в режим чтения.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.