Qual è lo scopo del metodo flip di ByteBuffer? (E perché si chiama "flip"?)


95

Perché il metodo flip () di ByteBuffer si chiama "flip"? Cosa significa "capovolto" qui? Secondo apidoc, due lanci successivi non ripristineranno lo stato originale e più lanci tenderanno probabilmente limit()a diventare zero.

Posso "sbloccare" in qualche modo per riutilizzare i byte che hanno superato un limite?

Posso concatenare la coda da capovolgere con altri dati?


5
"Capovolge" il buffer da lettura a scrittura (e viceversa). thushw.blogspot.com/2009/10/…
Brian Roach,

2
@BrianRoach: passa da lettura a scrittura ma non è così utile da scrivere a leggere a meno che tu non stia scrivendo strutture a dimensione fissa. Per lanciare per scrivere per leggere, usa resetinvece.
nneonneo

Ricordati di porre domande "oggettive"; o, almeno, fai sembrare oggettiva la domanda predominante: D

@nneonneo - Non era una domanda, non avrei dedicato molto tempo a spiegare i dettagli, quindi solo un commento e un collegamento.
Brian Roach

Risposte:


130

Un caso d'uso abbastanza comune per ByteBufferè quello di costruire una struttura dati pezzo per pezzo e poi scrivere l'intera struttura su disco. flipè usato per cambiare ByteBufferda "lettura da I / O" ( putting) a "scrittura su I / O" ( getting): dopo che una sequenza di puts è stata usata per riempire ByteBuffer, flipimposterà il limite del buffer alla posizione corrente e azzerare la posizione. Questo ha l'effetto di creare un futuro geto writedal buffer scrivere tutto ciò che era putnel buffer e non di più.

Dopo aver terminato put, potresti voler riutilizzare ByteBufferper costruire un'altra struttura dati. Per "sbloccarlo", chiama clear. Questo reimposta il limite alla capacità (rendendo utilizzabile tutto il buffer) e la posizione a 0.

Quindi, uno scenario di utilizzo tipico:

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

Che tipo di out?
Suzan Cioc

6
O qualsiasi altra cosa che abbia un write(ByteBuffer)metodo. (Non è realmente rilevante quale sia il suo tipo ...)
Stephen C

1
Dovrebbe Buffer.clearripristinare il limite alla capacità e la posizione a 0. Buffer.resetripristinare solo la posizione a mark.
Kelvin Ng

1
@KelvinNg: hai ragione; Ho modificato la risposta per riflettere questo. Grazie per la bella cattura!
nneonneo

1
@ user963241: lettura da I / O nel buffer, scrittura da tampone in I / O.
nneonneo

7

Flip assegna il valore di posizione corrente alla proprietà limit e imposta la proprietà position su 0. Flip è utile per drenare solo gli elementi attivi da un buffer.

Ad esempio, il programma seguente stampa "ciao" non elementi vuoti del buffer. Il metodo chiama limite e posizione può essere sostituito con 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());
}

Vedere http://www.zoftino.com/java-nio-tutorial per ulteriori informazioni su buffer e canali.


Grazie per il collegamento alla copertura molto ampia! È fantastico quando le fonti sono incluse. I documenti dell'API Java sembravano usare la parola "capovolgi" senza spiegazione, come se fosse un termine comune di informatica, ma ovviamente alcune persone (me compreso) non lo hanno trovato.
John Meyer

3

ByteBuffer è mal progettato. Ci sono molte lamentele da parte di programmatori decenti.

Quindi non cercare di ragionare su questo, studia e usa attentamente l'API.

Ora non posso parlarne male senza presentare un'alternativa, quindi eccolo:

Un buffer ha un valore fisso capacity; mantiene 2 puntatori: starte end. get()restituisce il byte nella startposizione e incrementa start. put()mette il byte nella endposizione e incrementa end. No flip()!


6
Allora, quali sono le lamentele? Se hai qualche lamentela personale va bene anche questo, ma non basta dire "X API fa schifo, la gente l'ha detto".
nneonneo

13
Pubblicare quel link è letteralmente tutto ciò che dovevi fare in primo luogo. Non ti ho mai accusato di mentire, ti ho semplicemente chiesto di approfondire l'origine e la natura delle denunce.
nneonneo

2
questo è solo un luogo in cui le persone offrono il loro aiuto volontariamente, con la giusta quantità di impegno che scelgono. Non ho bisogno di espandere ogni risposta in un documento accademico ben studiato.
irreputabile

8
e questo è anche un luogo in cui le persone non accettano la parola di qualcuno a meno che non sembri credibile.
arunmoezhi

8
Non hai nemmeno bisogno di fornire fonti. È palesemente ovvio che ByteBuffer è mal progettato. flip non soddisfa uno scopo, introduce solo una fonte di bug quando ti dimentichi di capovolgere. Se hanno sentito un'urgenza incontrollabile di inserirlo, almeno rendere ByteBuffer capovolti e non ribaltati classi diverse, in modo che il sistema dei tipi possa catturare i bug.
Gurgeh

0

Il metodo flip () prepara un buffer per una nuova sequenza di operazioni di scrittura sul canale o di acquisizione relativa: imposta il limite alla posizione corrente e quindi imposta la posizione a zero.

Il buffer tiene traccia dei dati scritti in esso. Dopo la scrittura, viene chiamato il metodo flip () per passare dalla modalità di scrittura a quella di lettura.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.