Quiero almacenar algunos datos en conjuntos de bytes en Java. Básicamente solo números que pueden tomar hasta 2 Bytes por número.
Me gustaría saber cómo puedo convertir un número entero en una matriz de bytes de 2 bytes de largo y viceversa. Encontré muchas soluciones en Google, pero la mayoría de ellas no explican qué sucede en el código. Hay muchas cosas cambiantes que realmente no entiendo, así que agradecería una explicación básica.
java
types
endianness
Chris
fuente
fuente
Respuestas:
Utilice las clases que se encuentran en el
java.nio
espacio de nombres, en particular, elByteBuffer
. Puede hacer todo el trabajo por ti.fuente
ByteBuffer
.wrap
yallocate
, no devuelven una instancia de la clase abstractaByteBuffer
.Char
,Short
,Int
. Supongo que podría rellenar a 4 bytes y descartar el cuarto cada vez, pero preferiría que no.Cuando se empaquetan bytes firmados en un int, cada byte debe enmascararse porque tiene un signo extendido a 32 bits (en lugar de cero extendido) debido a la regla de promoción aritmética (descrita en JLS, Conversiones y Promociones).
Hay un rompecabezas interesante relacionado con esto descrito en Java Puzzlers ("Una gran delicia en cada byte") de Joshua Bloch y Neal Gafter. Al comparar un valor de byte con un valor int, el byte se amplía con signo a un int y luego este valor se compara con el otro int
Tenga en cuenta que todos los tipos numéricos están firmados en Java, con la excepción de que char es un tipo entero sin signo de 16 bits.
fuente
& 0xFF
s son innecesarios.& 0xFF
s son necesarios ya que le dice a la JVM que convierta el byte firmado en un entero con solo esos bits establecidos. De lo contrario, el byte -1 (0xFF) se convertirá en int -1 (0xFFFFFFFF). Podría estar equivocado e incluso si lo estoy, no duele y aclara las cosas.byte b = 0; b |= 0x88; System.out.println(Integer.toString(b, 16)); //Output: -78 System.out.println(Integer.toString(b & 0xFF, 16)); //Output: 88
byte
la 0xFF (int
), JVM emitir elbyte
queint
con 1 extendida o 0 extendido según el líder de la primera bits. No hay byte sin firmar en Java, losbyte
s siempre están firmados.ByteBuffer.getInt()
:,Reads the next four bytes at this buffer's current position
solo se analizarán los primeros 4 bytes, que no deberían ser lo que desea.También puede usar BigInteger para bytes de longitud variable. Puede convertirlo a largo, int o corto, lo que se ajuste a sus necesidades.
o para denotar polaridad:
Para recuperar bytes solo:
fuente
intValueExact
, nointValue
Una implementación básica sería algo como esto:
Para entender las cosas, puede leer este artículo de WP: http://en.wikipedia.org/wiki/Endianness
Se mostrará el código fuente anterior
34 12 78 56 bc 9a
. Los primeros 2 bytes (34 12
) representan el primer entero, etc. El código fuente anterior codifica enteros en formato little endian.fuente
fuente
Alguien con un requisito en el que tiene que leer desde bits, digamos que tiene que leer desde solo 3 bits pero necesita un entero con signo y luego use lo siguiente:
El número mágico
3
se puede reemplazar con el número de bits (no bytes) que está utilizando.fuente
Como a menudo, la guayaba tiene lo que necesitas.
Para ir de una matriz de bytes a int:
Ints.fromBytesArray
doc aquíPara ir de la matriz de bytes a int:
Ints.toByteArray
doc aquífuente
Creo que este es el mejor modo para enviar a int
primer byte convertido a String
el siguiente paso es convertir a un int
pero el byte está en la rabia de -128 a 127 para esta razón, creo que es mejor usar la rabia de 0 a 255 y solo necesitas hacer esto:
fuente