2013-05-09 14 views
16

Mam świadomość, że flip() ustawia bieżącą pozycję bufora na 0 i ustawia limit poprzedniej pozycji bufora, podczas gdy rewind() po prostu ustawia bieżącą pozycję bufora na 0.różnica między bytebuffer.flip() i bytebuffer.rewind()

W poniższym kodzie albo używam rewind() lub flip() otrzymuję taki sam wynik.

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

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

Czy możesz podać mi prawdziwy przykład, w którym różnica tych dwóch metod ma znaczenie? Z góry dziękuję. EDYCJA: Znalazłem rozwiązanie w linku this, jest ono bardzo dobrze objaśnione i szczegółowe, aby dokładnie zrozumieć użycie bufora i klas kanałów.

Odpowiedz

7

Nie są one w ogóle równoważne.

A ByteBuffer jest zwykle gotowy do read() (lub do).

flip() przygotowuje dla write() (lub dla get()).

rewind() i compact() i clear() przygotowania go do read()/put() ponownie po write() (lub get()).

+0

Czy możesz mi powiedzieć, dlaczego piszesz 'read()/put()' i 'write()/get () '? Czy nie powinno to być 'read()/get()' i 'write()/put()'? Ponieważ uzyskanie operacji oznacza czytanie i używanie oznacza pisanie? – user963241

1

Metoda rewind() jest podobna do metody flip(), ale nie wpływa na ograniczenie. Ustawia tylko pozycję z powrotem na 0. Możesz użyć funkcji rewind(), aby wrócić i ponownie odczytać dane w buforze, który został już odwrócony. Typową sytuacją byłaby sytuacja: po użyciu funkcji flip() odczytano dane z bufora, które chcesz ponownie odczytać, metoda ta działałaby.

1

Oto przykład, w którym dwa będą dawały różne wyniki. Tak jak powiedziałeś, obie ustawiają pozycję na 0, różnica między nimi jest taka, że ​​klapki ustalają limit do poprzedniej pozycji.

Tak więc przy flipie, jeśli pisałeś (wstawiłeś), limit czytania (get) stanie się pozycją ostatniego napisanego przez ciebie elementu. Jeśli spróbujesz przeczytać coś więcej, spowoduje to wyjątek.

Rewind pozostawia limit bez zmian. Zakładając, że jest to pojemność (rozmiar bufora), pozwoli ci na dalsze czytanie poza danymi, które faktycznie zapisałeś, w tym przypadku odczytanie zer początkowych, od których zainicjowano bufor.

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 
2

Z kodu źródłowego są bardzo podobne. można zobaczyć następujące:

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

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

Więc różni się flip ustawić limit do position, natomiast rewind nie. Rozważmy zostały przydzielone bufor o wielkości 8, wypełnieniu bufora z 4 bajtów, wówczas pozycja jest ustawiona na 3, po prostu pokazać się następująco:

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

Więc rewind prostu stosować limitu odpowiednio ustawione.

0

@ user963241 Aby dodać więcej kolorów do odpowiedzi @ EJP.

klapką() sprawia, że ​​jest gotowy do zapisu() (lub get())

get() Przykład;

Może chcesz odczytać dane z bufora (Zakładając, że początkowo przechowywano go tam) i użyć go do czegoś innego, takich jak konwersja na łańcuch i manipulować go do dalszego wykorzystania.

ByteBuffer buf = ByteBuffer.allocateDirect(80); 
private String method(){ 
buf.flip(); 
byte[] bytes = byte[10]; //creates a byte array where you can place your data 
buf.get(bytes); //reads data from buffer and places it in the byte array created above 
return bytes; 
} 

write() Przykład; Po przeczytaniu danych z kanału gniazda do bufora możesz napisać go z powrotem do kanału gniazda - zakładając, że chcesz zaimplementować coś w rodzaju serwera, który odbiera tę samą wiadomość odebraną od klienta.

Więc będziesz czytać z kanału do bufora oraz bufor z powrotem do kanału

SocketChannel socketChannel = SocketChannel.open(); 
... 

ByteBuffer buf = ByteBuffer.allocateDirect(80); 

int data = socketChannel.read(buf); // Reads from channel and places it into the buffer 
while(data != -1){ //checks if not end of reading 
buf.flip();  //prepares for writing 
.... 
socketChannel.write(buf) // if you had initially placed data into buf and you want to read 
         //from it so that you can write it back into the channel 


    }