Je souhaite stocker des données dans des tableaux d'octets en Java. Fondamentalement, juste des nombres qui peuvent prendre jusqu'à 2 octets par nombre.
J'aimerais savoir comment je peux convertir un entier en un tableau d'octets de 2 octets et vice versa. J'ai trouvé beaucoup de solutions sur Google, mais la plupart n'expliquent pas ce qui se passe dans le code. Il y a beaucoup de choses changeantes que je ne comprends pas vraiment, alors j'apprécierais une explication de base.
java
types
endianness
Chris
la source
la source
Réponses:
Utilisez les classes trouvées dans l'
java.nio
espace de noms, en particulier leByteBuffer
. Il peut faire tout le travail pour vous.la source
ByteBuffer
.wrap
etallocate
, elles ne renvoient pas une instance de la classe abstraiteByteBuffer
.Char
,Short
,Int
. Je suppose que je pourrais ajouter 4 octets et supprimer le 4e à chaque fois, mais je préfère ne pas le faire.Lors du regroupement d'octets signés dans un entier, chaque octet doit être masqué car il est étendu par signe à 32 bits (plutôt que zéro) en raison de la règle de promotion arithmétique (décrite dans JLS, Conversions et Promotions).
Il y a un casse-tête intéressant lié à cela décrit dans Java Puzzlers ("Un grand plaisir dans chaque octet") par Joshua Bloch et Neal Gafter. Lors de la comparaison d'une valeur d'octet à une valeur int, l'octet est étendu par signe à un int, puis cette valeur est comparée à l'autre int
Notez que tous les types numériques sont signés en Java, à l'exception du fait que char est un type entier non signé 16 bits.
la source
& 0xFF
s ne sont pas nécessaires.& 0xFF
s sont nécessaires car il indique à la JVM de convertir l'octet signé en un entier avec uniquement ces bits définis. Sinon, l'octet -1 (0xFF) se transforme en int -1 (0xFFFFFFFF). Je peux me tromper et même si je le suis, cela ne fait pas mal et rend les choses plus claires.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
avec 0xFF (int
), JVM chassera l'byte
àint
avec 1 étendu ou 0 extension de selon le premier bit le premier. Il n'y a pas d'octet non signé en Java, lesbyte
s sont toujours signés.ByteBuffer.getInt()
:Reads the next four bytes at this buffer's current position
, seuls les 4 premiers octets sera analysée, ce qui ne devrait pas être ce que vous voulez.Vous pouvez également utiliser BigInteger pour les octets de longueur variable. Vous pouvez le convertir en long, int ou short, selon vos besoins.
ou pour désigner la polarité:
Pour récupérer des octets simplement:
la source
intValueExact
pasintValue
Une implémentation de base serait quelque chose comme ceci:
Afin de comprendre les choses, vous pouvez lire cet article WP: http://en.wikipedia.org/wiki/Endianness
Le code source ci-dessus sera généré
34 12 78 56 bc 9a
. Les 2 premiers octets (34 12
) représentent le premier entier, etc. Le code source ci-dessus encode les entiers au format little endian.la source
la source
Quelqu'un avec une exigence où ils doivent lire à partir de bits, disons que vous devez lire à partir de seulement 3 bits mais vous avez besoin d'un entier signé, puis utilisez ce qui suit:
Le nombre magique
3
peut être remplacé par le nombre de bits (et non d'octets) que vous utilisez.la source
Comme souvent, la goyave a ce dont vous avez besoin.
Pour passer du tableau d'octets à int:,
Ints.fromBytesArray
doc iciPour passer du tableau int au tableau d'octets:,
Ints.toByteArray
doc icila source
je pense que c'est le meilleur mode de diffusion en int
premier octet de conversion en chaîne
la prochaine étape est de passer à un int
mais l'octet est en rage de -128 à 127 pour cette raison, je pense qu'il vaut mieux utiliser rage 0 à 255 et il vous suffit de faire ceci:
la source