2013-05-09 10 views
16

Sono consapevole che flip() imposta la posizione del buffer corrente su 0 e imposta il limite sulla posizione del buffer precedente mentre rewind() imposta semplicemente la posizione del buffer corrente su 0.differenza tra bytebuffer.flip() e bytebuffer.rewind()

Nel seguente codice, o utilizzo rewind() o flip() ottengo lo stesso risultato.

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

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

Potrebbe fornirmi un esempio reale in cui la differenza tra questi due metodi è davvero importante? Grazie in anticipo. EDIT: Ho trovato la soluzione nel collegamento this, è molto ben spiegata e dettagliata per una conoscenza approfondita dell'uso del buffer e delle classi di canali.

risposta

7

Non sono affatto equivalenti.

A ByteBuffer è normalmente pronto per read() (o per put()).

flip() rende pronto per write() (o per get()).

rewind() e compact() e clear() renderlo pronto per read()/put() di nuovo dopo write() (o get()).

+0

Può cortesemente dirmi perché hai scritto 'read()/put()' e 'write()/get () '? Non dovrebbe essere 'read()/get()' e 'write()/put()'? Dal momento che ottenere un'operazione significa leggere e mettere implica scrivere? – user963241

1

Il metodo rewind() è simile a flip() ma non influisce sul limite. Imposta solo la posizione su 0. È possibile utilizzare rewind() per tornare indietro e rileggere i dati in un buffer che è già stato capovolto. Una situazione comune sarebbe: dopo aver usato flip(), hai letto i dati dal buffer, vuoi rileggere i dati, questo metodo funzionerebbe.

1

Ecco un esempio in cui i due genereranno risultati diversi. Come hai detto, entrambi impostano la posizione su 0, la differenza tra i due è che il flip imposta il limite alla posizione precedente.

Quindi con il flip, se stavi scrivendo (put), il limite per la lettura (get) diventerà la posizione dell'ultimo elemento che hai scritto. Se provi a leggere qualcosa di più, genererà un'eccezione.

Rewind lascia il limite invariato. Supponendo che fosse a capacità (dimensione del buffer), ti permetterà di continuare a leggere oltre i dati che hai effettivamente scritto, in questo caso leggendo gli zeri iniziali con cui è stato inizializzato il buffer.

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

Dal codice sorgente, sono molto simili. Si può vedere il seguito:

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

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

Così il diverso è il flip impostare il limit-position, mentre rewind no. Considerate aver allocato un buffer con 8 dimensioni, aver riempito il buffer di 4 byte, allora la posizione è impostato su 3, solo mostrare come seguono:

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

Così rewind limite appena usato è impostato in modo appropriato.

0

@ user963241 Per aggiungere altro colore alla risposta di @ EJP.

vibrazione() rende pronta per scrive() (o get())

get() Esempio;

Si potrebbe desiderare di leggere i dati dal buffer (supponendo che si era inizialmente conservato in là) e usarlo per qualcos'altro come la conversione in una stringa e manipolarlo per un ulteriore uso.

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() Esempio; Dopo aver letto i dati dal canale socket nel buffer, è possibile che si desideri scriverlo sul canale socket, presupponendo che si desideri implementare qualcosa come un server che riproduce lo stesso messaggio ricevuto dal client.

Così si leggerà da canale a buffer e dal back buffer al canale

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 


    }