¿Cuál es el propósito del método flip de ByteBuffer? (¿Y por qué se llama "flip"?)

95

¿Por qué el método flip () de ByteBuffer se llama "flip"? ¿Qué es "volteado" aquí? Según apidoc, dos giros sucesivos no restaurarán el estado original, y varios giros probablemente tenderán limit()a convertirse en cero.

¿Puedo "deshacer" de alguna manera para reutilizar los bytes que se salieron de un límite?

¿Puedo concatenar la cola para voltearla con otros datos?

Suzan Cioc
fuente
5
"Voltea" el búfer de lectura a escritura (y viceversa). thushw.blogspot.com/2009/10/…
Brian Roach
2
@BrianRoach: cambia de lectura a escritura, pero no es tan útil para escritura como lectura a menos que esté escribiendo estructuras de tamaño fijo. Para voltear para escribir para leer, use reseten su lugar.
nneonneo
Recuerde hacer preguntas "objetivas"; o, al menos, hacer que la pregunta predominante parezca objetiva: D
@nneonneo - No era una pregunta, realmente no iba a dedicar mucho tiempo a explicar los detalles, por lo tanto, solo un comentario y un enlace.
Brian Roach

Respuestas:

130

Un caso de uso bastante común para el ByteBufferes construir una estructura de datos pieza por pieza y luego escribir esa estructura completa en el disco. flipse usa para cambiar ByteBufferde "lectura de E / S" ( putting) a "escribir en I / O" ( getting): después de que putse usa una secuencia de s para llenar el ByteBuffer, flipestablecerá el límite del búfer en la posición actual y restablezca la posición a cero. Esto tiene el efecto de hacer que un futuro geto writedesde el búfer escriba todo lo que estaba puten el búfer y nada más.

Después de terminar put, es posible que desee reutilizarlo ByteBufferpara construir otra estructura de datos. Para "abrirlo", llame clear. Esto restablece el límite de la capacidad (haciendo que todo el búfer sea utilizable) y la posición a 0.

Entonces, un escenario de uso típico:

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);
}
neonneo
fuente
¿Qué es un tipo de out?
Suzan Cioc
6
O cualquier otra cosa que tenga un write(ByteBuffer)método. (No es realmente relevante cuál es su tipo ...)
Stephen C
1
Debería Buffer.clearrestablecer el límite a la capacidad y la posición a 0. Buffer.resetRestablecer solo la posición a mark.
Kelvin Ng
1
@KelvinNg: Tienes razón; He modificado la respuesta para reflejar esto. ¡Gracias por la buena captura!
nneonneo
1
@ user963241: leer de E / S en búfer, escribir de búfer en E / S.
nneonneo
7

Flip asigna el valor de posición actual a la propiedad de límite y establece la propiedad de posición en 0. Flip es útil para drenar solo elementos activos de un búfer.

Por ejemplo, el programa siguiente imprime "hola", no elementos vacíos del búfer. El límite y la posición de las llamadas al método se pueden reemplazar 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());
}

Consulte http://www.zoftino.com/java-nio-tutorial para obtener más información sobre búferes y canales.

Arnav Rao
fuente
¡Gracias por el enlace a la amplia cobertura! Es genial cuando se incluyen las fuentes. Los documentos de la API de Java parecían usar la palabra 'flip' sin explicación, como si fuera un término común de la informática, pero obviamente algunas personas (incluyéndome a mí) no han encontrado que ese sea el caso.
John Meyer
3

ByteBuffer está mal diseñado. Hay muchas quejas de programadores decentes.

Así que no intente razonar al respecto, solo estudie y use la API con cuidado.

Ahora no puedo hablar mal de él sin presentar una alternativa, así que aquí está:

Un búfer tiene un fijo capacity; mantiene 2 punteros: starty end. get()devuelve el byte en la startposición y se incrementa start. put()coloca el byte en la endposición y lo incrementa end. flip()¡ No !

irrefutable
fuente
6
Entonces, ¿cuáles son las quejas? Si tiene alguna queja personal, también está bien, pero no está bien decir "X API apesta, la gente lo dice".
nneonneo
13
Publicar ese enlace es literalmente todo lo que tenía que hacer en primer lugar. Nunca lo acusé de mentir, simplemente le pedí que explicara el origen y la naturaleza de las quejas.
nneonneo
2
este es solo un lugar donde las personas ofrecen su ayuda voluntariamente, con la cantidad adecuada de esfuerzo que elijan. No necesito expandir cada respuesta en un artículo académico bien investigado.
irrefutable
8
y este es también un lugar donde la gente no acepta la palabra de alguien a menos que suene creíble.
arunmoezhi
8
Ni siquiera necesitas dar fuentes. Es descaradamente obvio que ByteBuffer está mal diseñado. flip no cumple un propósito, solo introduce una fuente de errores cuando te olvidas de voltear. Si sintieron una necesidad incontrolable de ponerlo, al menos cree clases diferentes de ByteBuffers volteados y sin voltear, para que el sistema de tipos pueda detectar los errores.
Gurgeh
0

El método flip () prepara un búfer para una nueva secuencia de operaciones de escritura de canal o de obtención relativa: establece el límite en la posición actual y luego establece la posición en cero.

Buffer realiza un seguimiento de los datos escritos en él. Después de escribir, se llama al método flip () para cambiar del modo de escritura al modo de lectura.

vkohli
fuente