ByteBuffer resumen de operaciones de lectura y escritura de bytes y formato de datos espaciales MySql Ejemplos de lectura y escritura de geometría

ByteBuffer

El
búfer de bytes de la clase ByteBuffer en el
padre NIO ByteBuffer es la clase Buffer, es decir, clases de búfer, búfer de bytes ByteBuffer, por supuesto, puede manejar int, long, char y otros tipos de datos básicos.

En comparación con las otras clases heredadas de la clase Buffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer y ShortBuffer, la clase ByteBuffer se usa más ampliamente.

La clase de implementación es la siguiente:

Clase de implementación descripción ventaja
HeapByteBuffer Un búfer en el montón de jvm, la capa inferior es esencialmente una matriz Dado que el contenido se mantiene en el jvm, será más rápido escribir el contenido en el búfer; y se puede reciclar más fácilmente.
DirectByteBuffer Los datos subyacentes se mantienen en la memoria del sistema operativo, no en el jvm. DirectByteBuffer mantiene una dirección de referencia que apunta a los datos para manipularlos. Tratar con periféricos (dispositivos IO) será mucho más rápido, porque cuando los periféricos leen los datos en el montón de jvm, no se leen directamente, sino que leen los datos en el jvm en un bloque de memoria, y luego en este bloque Para leer, si usa DirectByteBuffer, puede omitir este paso y lograr una copia cero

Propiedades y métodos de ByteBuffer

Propiedades de ByteBuffer
  • byte [] buff buffer array // buff es el arreglo utilizado internamente para el almacenamiento en búfer.
  • capacidad // Capacidad en la inicialización.
  • Limitar limitar el área crítica del búfer, es decir, qué posición se puede leer como máximo
    • Al escribir datos en el búfer, el límite es generalmente igual a la capacidad .
    • Al leer datos , el límite representa la longitud de datos válidos en el búfer .
  • int position = 0 Posición // Posición leída actualmente.
  • int mark = -1 Marcar // Un subíndice de ubicación de almacenamiento temporal, para marcar una ubicación de lectura, de modo que pueda devolverse a esa ubicación en algún momento.
  • Llamar a mark () establecerá la marca en el valor de posición actual, y llamar a reset () más tarde establecerá la propiedad de posición en el valor de marca.
  • El valor de la marca es siempre menor o igual que el valor de la posición. Si el valor de la posición se establece por debajo de la marca, el valor de la marca actual se descartará.

Estos atributos siempre satisfacen las siguientes condiciones:
  0 <= marca <= posición <= límite <= capacidad

Métodos comunes de ByteBuffer
  • ByteBuffer allocate (int capacity) // Crea un ByteBuffer con una capacidad especificada .

  • ByteBuffer allocateDirect (int capacidad) // Cree un ByteBuffer directo, tal ByteBuffer tendrá un mejor rendimiento al participar en operaciones IO

  • ByteBuffer wrap (byte [] array) // Envuelve una matriz de bytes en ByteBuffer .

  • ByteBuffer wrap (byte [] array, int offset, int length) // Envuelve una matriz de bytes o parte de una matriz de bytes en un ByteBuffer.

  • Buffer clear () Establece la posición en 0 y el límite de capacidad. Generalmente se llama antes de escribir datos en Buffer .

  • Buffer flip () Establece el límite en la posición actual y la posición en 0. Por lo general, se llama antes de leer los datos del búfer .

  • Buffer rewind () Establece la posición en 0 y el límite no cambia. Por lo general, se llama antes de reescribir los datos en el búfer .

  • compact () copia los datos entre posición y límite al principio del búfer. Después de copiar, posición = límite -posición, límite = capacidad, pero si no hay datos entre posición y límite, no se copiará.

  • mark () & reset () Al llamar al método Buffer.mark (), puede marcar una posición específica en el búfer. Posteriormente, se puede restaurar a esta posición llamando al método Buffer.reset ().

  • int restantes () elementos legibles restantes, posición límite

  • boolean isReadOnly () es un búfer legible

  • boolean isDirect () es memoria fuera del montón

  • // ponte

    • byte get (índice int)
    • ByteBuffer poner (byte b)
    • int getInt () // Lee un valor int del ByteBuffer.
    • ByteBuffer putInt (valor int) // escribe un valor int en ByteBuffer.
    • xxx

Pedido de punto final

orden de almacenamiento de bytes endian

Endianness, como su nombre lo indica, el orden de los bytes, dos palabras más son el orden de almacenamiento de datos de más de un tipo de byte en la memoria (por supuesto, no es necesario hablar del orden de un byte de datos).

  • LITTLE-ENDIAN (little endian , low endian), es decir, el byte bajo se coloca en el extremo de la dirección baja de la memoria, y el byte alto se coloca en el extremo de la dirección alta de la memoria.
  • Correspondiente a él es: BIG-ENDIAN (big endian, high endian)

Endianness en diferentes lenguajes y escenarios

La secuencia predeterminada de JAVA es Big-Endian big end

El protocolo TCP / IP define el orden de bytes como Big-Endian , por lo que el orden de bytes utilizado en el protocolo TCP / IP generalmente se denomina orden de bytes de red.

Ejemplo de código

Orden de gran final

ByteBuffer byteBuffer = ByteBuffer.allocate(4);
byteBuffer.order(ByteOrder.BIG_ENDIAN);
byteBuffer.putInt(88);
byte[] result = byteBuffer.array();
System.out.println(Arrays.toString(result));

Imprimir [0,0,0,88]

Pedido final pequeño

ByteBuffer byteBuffer = ByteBuffer.allocate(4);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
byteBuffer.putInt(88);
byte[] result = byteBuffer.array();
System.out.println(Arrays.toString(result));

Imprimir [88,0,0,0]

Leer datos

Cuando el flip
comience a leer, restablezca la posición a 0 y establezca el límite en la posición actual. (Se usa al escribir y transferir)

get
lee un byte del búfer y mueve la posición en uno. El límite superior es el límite, que es la última posición de los datos escritos.

borrar
la capacidad límite se establece en el tamaño, la posición se establece en 0 y no borra el contenido del búfer .

Escribir datos

En el
modo de escritura, escriba un byte en el búfer y mueva la posición un bit. En el modo de escritura, el límite y la capacidad son generalmente iguales.

Ejemplo

Practica una ola con Geometría de tipo de datos espaciales Mysql

El formato de almacenamiento real de Geometry es: 25 bytes de longitud

  • 4 bytes para SRID entero (0)
  • 1 byte (orden de bytes entero) (1 = little endian)
  • 4 bytes para información de tipo entero
  • Coordenada X de doble precisión de 8 bytes
  • Coordenada Y de doble precisión de 8 bytes

Por ejemplo, POINT(1 -1)consta de la siguiente secuencia de 25 bytes, cada secuencia está representada por dos dígitos hexadecimales :

mysql> SET @g = ST_GeomFromText('POINT(1 -1)');
mysql> SELECT LENGTH(@g);
+------------+
| LENGTH(@g) |
+------------+
|         25 |
+------------+
mysql> SELECT HEX(@g);
+----------------------------------------------------+
| HEX(@g)                                            |
+----------------------------------------------------+
| 000000000101000000000000000000F03F000000000000F0BF |
+----------------------------------------------------+
composición Talla valor
SRID 4 bytes 00000000
Orden de bytes 1 byte 01
Tipo WKB 4 bytes 01000000
Coordenada X 8 bytes 000000000000F03F
Coordenada Y 8 bytes 000000000000F0BF

Leer PUNTO

        // 模拟 POINT(1 -1)
        String pointstr = "000000000101000000000000000000F03F000000000000F0BF";
        byte[] bytes = HexUtil.decodeHex(pointstr);
        // 开始
        ByteBuffer wrap = ByteBuffer.wrap(bytes)
                .order(ByteOrder.LITTLE_ENDIAN);// 小端点排序(Java默认是大端点排序,这里要改下)
        int SRID = wrap.getInt();
        byte endian = wrap.get();
        int wkbType = wrap.getInt();
        double x = wrap.getDouble();
        double y = wrap.getDouble();
        System.out.println("SRID: " + SRID);
        System.out.println("endian: " + endian);
        System.out.println("wkbType: " + wkbType);
        System.out.println("x: " + x);
        System.out.println("y: " + y);
...
SRID: 0
endian: 1
wkbType: 1
x: 1.0
y: -1.0

Escribir PUNTO

        // 开始
        ByteBuffer wrap = ByteBuffer.allocate(25)
                .order(ByteOrder.LITTLE_ENDIAN);// 小端点排序(Java默认是大端点排序,这里要改下)
        wrap.putInt(0);// SRID: 0
        wrap.put((byte) 1);// endian: 1
        wrap.putInt(1);// wkbType: 1
        wrap.putDouble(1);// x: 1.0
        wrap.putDouble(-1);// y: -1.0
        byte[] array = wrap.array();
        String encodeHexStr = HexUtil.encodeHexStr(array, false);
        System.out.println(encodeHexStr);
...
000000000101000000000000000000F03F000000000000F0BF

referencia:

  • https://www.jianshu.com/p/ebc52832dca0
  • https://dev.mysql.com/doc/refman/5.7/en/gis-data-formats.html

Supongo que te gusta

Origin blog.csdn.net/abu935009066/article/details/114928627
Recomendado
Clasificación