Jaki jest cel metody odwracania ByteBuffer? (Dlaczego nazywa się to „flip”?)

96

Dlaczego metoda flip () ByteBuffera nazywa się „flip”? Co jest tutaj „odwrócone”? Według apidoc, dwa kolejne przewroty nie przywrócą pierwotnego stanu, a wielokrotne przewroty prawdopodobnie limit()staną się zerowe.

Czy mogę jakoś „odpiąć”, aby ponownie użyć bajtów, które przekroczyły limit?

Czy mogę połączyć tail, aby zostać odwróconym z innymi danymi?

Suzan Cioc
źródło
5
„Przerzuca” bufor z odczytu na zapis (i odwrotnie). thushw.blogspot.com/2009/10/…
Brian Roach
2
@BrianRoach: Przełącza się z odczytu na zapis, ale nie jest tak przydatny do zapisu do odczytu, chyba że piszesz struktury o stałym rozmiarze. Aby przewrócić, napisać i przeczytać, użyj resetzamiast tego.
nneonneo
Pamiętaj, aby zadawać „obiektywne” pytania; lub przynajmniej spraw, aby dominujące pytanie wydawało się obiektywne: D
@nneonneo - To nie było pytanie, nie zamierzałem spędzać dużo czasu na wyjaśnianiu szczegółów, stąd tylko komentarz i link.
Brian Roach

Odpowiedzi:

131

Jednym z dość powszechnych przypadków użycia ByteBufferjest konstruowanie struktury danych kawałek po kawałku, a następnie zapisywanie całej struktury na dysku. flipsłuży do zamiany ByteBufferz "odczytu z I / O" ( putting) na "zapis do I / O" ( getting): po zastosowaniu sekwencji puts do wypełnienia ByteBuffer, flipustawi limit bufora na bieżącą pozycję i zresetuj pozycję do zera. To powoduje, że przyszłość getlub writez bufora zapisują wszystko, co było putdo bufora i nic więcej.

Po zakończeniu putmożesz chcieć ponownie użyć ByteBufferdo skonstruowania innej struktury danych. Aby to „odpiąć”, zadzwoń clear. Spowoduje to zresetowanie limitu do pojemności (dzięki czemu cały bufor będzie nadający się do użytku), a pozycja na 0.

Tak więc typowy scenariusz użycia:

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);
}
nneonneo
źródło
A WritableByteChannel, na przykład FileChannellub SocketChannel.
nneonneo
6
Lub cokolwiek innego, co ma write(ByteBuffer)metodę. (Nie ma znaczenia, jaki jest jego typ ...)
Stephen C
1
Powinien, Buffer.clearktóry zresetować limit pojemności i pozycję do 0. Buffer.resetresetować tylko pozycję do mark.
Kelvin Ng
1
@KelvinNg: Masz rację; Poprawiłem odpowiedź, aby to odzwierciedlić. Dzięki za niezły połów!
nneonneo
1
@ user963241: odczyt z I / O do bufora, zapis z bufora do I / O.
nneonneo
7

Odwróć przypisuje bieżącą wartość pozycji do właściwości limit i ustawia właściwość pozycji na 0. Odwróć jest użyteczne, aby usunąć tylko aktywne elementy z bufora.

Na przykład, poniższy program wypisuje "hello", a nie puste elementy bufora. Limit wywołań metod i pozycja można zastąpić klapką.

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());
}

Więcej informacji na temat buforów i kanałów można znaleźć pod adresem http://www.zoftino.com/java-nio-tutorial .

Arnav Rao
źródło
Dziękuję za link do bardzo obszernej relacji! To wspaniałe, gdy uwzględnione są źródła. Dokumentacja Java API wydawała się używać słowa „flip” bez wyjaśnienia, jakby to był powszechny termin informatyczny, ale oczywiście kilka osób (w tym ja) nie odkryło, że tak jest.
John Meyer
3

ByteBuffer jest źle zaprojektowany. Jest wiele skarg od porządnych programistów.

Więc nie próbuj tego rozumować, po prostu przestudiuj i uważnie korzystaj z API.

Teraz nie mogę tego oszukać bez przedstawienia alternatywy, więc oto jest:

Bufor ma stałą capacity; zachowuje 2 wskaźniki: starti end. get()zwraca bajt na startpozycji i zwiększa start. put()umieszcza bajt na endpozycji i zwiększa end. Nie flip()!

nieoceniony
źródło
6
Więc jakie są skargi? Jeśli masz jakieś osobiste zażalenia, to też jest OK, ale nie wystarczy powiedzieć „X API jest do niczego, ludzie tak mówili”.
nneonneo
13
Umieszczenie tego linku to dosłownie wszystko, co musiałeś zrobić w pierwszej kolejności. Nigdy nie oskarżyłem cię o kłamstwo, poprosiłem cię jedynie o wyjaśnienie źródła i charakteru skarg.
nneonneo
2
jest to po prostu miejsce, w którym ludzie dobrowolnie oferują swoją pomoc, z odpowiednim wysiłkiem, na jaki się zdecydują. Nie muszę umieszczać każdej odpowiedzi w dobrze zbadanej pracy naukowej.
niezaprzeczalny
8
i jest to również miejsce, w którym ludzie nie uwierzą komuś na słowo, jeśli nie brzmi to wiarygodnie.
arunmoezhi
8
Nie musisz nawet podawać źródeł. Jest oczywiste, że ByteBuffer jest źle zaprojektowany. Flip nie wypełnia celu, po prostu wprowadza źródło błędów, gdy zapomnisz przewrócić. Jeśli poczuli niekontrolowaną chęć umieszczenia go, przynajmniej utwórz odwrócone i niezapięte ByteBuffers różne klasy, aby system typów mógł wychwycić błędy.
Gurgeh
0

metoda flip () przygotowuje bufor na nową sekwencję operacji zapisu kanałowego lub względnego pobierania: ustawia limit na bieżącą pozycję, a następnie ustawia pozycję na zero.

Bufor śledzi zapisane w nim dane. W celu przełączenia się z trybu pisania do trybu czytania wywoływana jest metoda flip () post writing .

vkohli
źródło