¿Para qué sirve ByteBuffer en Java? [cerrado]


199

¿Cuáles son las aplicaciones de ejemplo para a ByteBufferen Java? Enumere cualquier escenario de ejemplo donde se use esto. ¡Gracias!


1
La compresión de Apache Hadoop (códec zlib por ejemplo) usa ByteBuffer de jave.nio.
nikk

Bueno para enviar datos a GPU's.
Pixel

Respuestas:


138

Esta es una buena descripción de sus usos y deficiencias. Básicamente, lo usa cuando necesita hacer E / S rápidas de bajo nivel. Si fuera a implementar un protocolo TCP / IP o si estuviera escribiendo una base de datos (DBMS), esta clase sería útil.


3
¿Es útil en algún sitio web de alto tráfico desarrollado con Java y Cassandra DB?
Aklin

1
Después de una búsqueda rápida, parece que sí, Cassandra usa ByteBuffer: mail-archive.com/commits@cassandra.apache.org/msg14967.html Si se está preguntando acerca de un sitio web sin procesar, puede haberlo, pero generalmente es solo va a ser utilizado indirectamente por sitios web - mediante el uso de herramientas como cassandra
kelloti

1
No es un mal enlace, gracias. me gustaría añadir éste i encontraron útiles - worldmodscode.wordpress.com/2012/12/14/...
Peter Perháč

Enlace malo, me temo ...
RoyalBigMack

96

La clase ByteBuffer es importante porque forma una base para el uso de canales en Java. La clase ByteBuffer define seis categorías de operaciones sobre búferes de bytes, como se indica en la documentación de Java 7 :

  • Métodos de obtención y colocación absolutos y relativos que leen y escriben bytes individuales;

  • Los métodos de obtención masiva relativa que transfieren secuencias contiguas de bytes desde este búfer a una matriz;

  • Métodos de colocación masiva relativa que transfieren secuencias contiguas de bytes desde una matriz de bytes o algún otro búfer de bytes a este búfer;

  • Métodos de obtención y colocación absolutos y relativos que leen y escriben valores de otros tipos primitivos, traduciéndolos hacia y desde secuencias de bytes en un orden de bytes particular;

  • Métodos para crear memorias intermedias de vista, que permiten que una memoria intermedia de bytes se vea como una memoria intermedia que contiene valores de algún otro tipo primitivo; y

  • Métodos para compactar , duplicar y cortar un búfer de bytes.

Example code : Putting Bytes into a buffer.

    // Create an empty ByteBuffer with a 10 byte capacity
    ByteBuffer bbuf = ByteBuffer.allocate(10);

    // Get the buffer's capacity
    int capacity = bbuf.capacity(); // 10

    // Use the absolute put(int, byte).
    // This method does not affect the position.
    bbuf.put(0, (byte)0xFF); // position=0

    // Set the position
    bbuf.position(5);

    // Use the relative put(byte)
    bbuf.put((byte)0xFF);

    // Get the new position
    int pos = bbuf.position(); // 6

    // Get remaining byte count
    int rem = bbuf.remaining(); // 4

    // Set the limit
    bbuf.limit(7); // remaining=1

    // This convenience method sets the position to 0
    bbuf.rewind(); // remaining=7

56
La mayor parte de este comentario se copia de los documentos de Java 7 .
Janus Troelsen

66
A menos que esté aprovechando un efecto secundario no obvio, creo que puede estar usando el método incorrecto para una colocación absoluta. El Javadoc parece indicar que la colocación absoluta requiere un valor de índice.
Chuck Wolber el

66
incluso si es solo una copia del documento de la API, incluso con su puntaje bcs, algunas personas parecen ser demasiado flojas para echarle un vistazo.
Chris

1
Hay un error en uno de los ejemplos. El "put absoluto", pierde el primer parámetro que representa el índice (0 en este caso).
bvdb

21

Java IO utilizando API orientadas a la transmisión se realiza utilizando un búfer como almacenamiento temporal de datos dentro del espacio del usuario. Los datos leídos desde el disco por DMA se copian primero a las memorias intermedias en el espacio del núcleo, que luego se transfieren a la memoria intermedia en el espacio del usuario. Por lo tanto, hay gastos generales. Evitarlo puede lograr una ganancia considerable en el rendimiento.

Podríamos omitir este búfer temporal en el espacio del usuario, si hubiera una forma directa de acceder al búfer en el espacio del kernel. Java NIO proporciona una manera de hacerlo.

ByteBufferse encuentra entre varios buffers proporcionados por Java NIO. Es solo un contenedor o tanque de retención para leer o escribir datos. El comportamiento anterior se logra mediante la asignación de un búfer directo utilizando allocateDirect()API en el búfer.

La documentación de Java de Byte Buffer tiene información útil.


14

En Android, puede crear un búfer compartido entre C ++ y Java (con el método directAlloc) y manipularlo en ambos lados.


13

Aquí hay un gran artículo que explica los beneficios de ByteBuffer. Los siguientes son los puntos clave en el artículo:

  • La primera ventaja de un ByteBuffer independientemente de si es directo o indirecto es el acceso aleatorio eficiente de datos binarios estructurados (por ejemplo, IO de bajo nivel como se indica en una de las respuestas). Antes de Java 1.4, para leer dichos datos se podía usar un DataInputStream, pero sin acceso aleatorio.

Los siguientes son beneficios específicos para ByteBuffer / MappedByteBuffer directo. Tenga en cuenta que las memorias intermedias directas se crean fuera del montón:

  1. No se ven afectados por los ciclos gc : los buffers directos no se moverán durante los ciclos de recolección de basura ya que residen fuera del montón. La tecnología de almacenamiento en caché BigMemory de TerraCota parece depender en gran medida de esta ventaja. Si estuvieran en el montón, disminuiría los tiempos de pausa gc.

  2. Aumento del rendimiento : en el flujo de E / S, las llamadas de lectura implicarían llamadas del sistema, que requieren un cambio de contexto entre el usuario al modo kernel y viceversa, lo que sería costoso, especialmente si se accede constantemente al archivo. Sin embargo, con el mapeo de memoria, este cambio de contexto se reduce ya que es más probable que los datos se encuentren en la memoria (MappedByteBuffer). Si los datos están disponibles en la memoria, se accede directamente sin invocar el sistema operativo, es decir, sin cambio de contexto.

Tenga en cuenta que MappedByteBuffers es muy útil, especialmente si los archivos son grandes y se accede con más frecuencia a pocos grupos de bloques.

  1. Uso compartido de páginas : los archivos mapeados de memoria se pueden compartir entre procesos, ya que se asignan en el espacio de memoria virtual del proceso y se pueden compartir entre procesos.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.