Ich möchte einige Daten in Byte-Arrays in Java speichern. Grundsätzlich nur Zahlen, die bis zu 2 Bytes pro Zahl aufnehmen können.
Ich möchte wissen, wie ich eine Ganzzahl in ein 2 Byte langes Byte-Array konvertieren kann und umgekehrt. Ich habe viele Lösungen gefunden, die googeln, aber die meisten erklären nicht, was im Code passiert. Es gibt viele wechselnde Dinge, die ich nicht wirklich verstehe, daher würde ich mich über eine grundlegende Erklärung freuen.
java
types
endianness
Chris
quelle
quelle
Antworten:
Verwenden Sie die im
java.nio
Namespace gefundenen Klassen , insbesondere dieByteBuffer
. Es kann die ganze Arbeit für Sie erledigen.quelle
ByteBuffer
.wrap
und meinenallocate
, geben sie keine Instanz der abstrakten Klasse zurückByteBuffer
.Char
,Short
,Int
. Ich nehme an, ich könnte jedes Mal auf 4 Bytes auffüllen und das 4. verwerfen, aber ich würde es lieber nicht tun.Beim Packen von vorzeichenbehafteten Bytes in ein int muss jedes Byte maskiert werden, da es aufgrund der arithmetischen Heraufstufungsregel (beschrieben in JLS, Conversions and Promotions) auf 32 Bit vorzeichenerweitert (anstatt auf null erweitert) ist.
Es gibt ein interessantes Puzzle, das in Java Puzzlers ("Eine große Freude in jedem Byte") von Joshua Bloch und Neal Gafter beschrieben ist. Beim Vergleichen eines Bytewerts mit einem int-Wert wird das Byte vorzeichenerweitert zu einem int und dieser Wert wird dann mit dem anderen int verglichen
Beachten Sie, dass alle numerischen Typen in Java signiert sind, mit Ausnahme von char, einem 16-Bit-Integer-Typ ohne Vorzeichen.
quelle
& 0xFF
s sind unnötig.& 0xFF
s ist notwendig, da es die JVM anweist , das vorzeichenbehaftete Byte in eine Ganzzahl umzuwandeln, wobei nur diese Bits gesetzt sind. Andernfalls wird das Byte -1 (0xFF) zum int -1 (0xFFFFFFFF). Ich könnte mich irren und selbst wenn ich es bin, tut es nicht weh und macht die Dinge klarer.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
mit 0xFF (int
) wird JVM werfen diebyte
aufint
mit 1 verlängert oder 0 erweitert die nach dem führenden Bit zuerst. In Java gibt es kein vorzeichenloses Byte ,byte
s sind immer signiert.ByteBuffer.getInt()
:Reads the next four bytes at this buffer's current position
nur die ersten 4 Bytes analysiert, was nicht das sein sollte, was Sie wollen.Sie können BigInteger auch für Bytes variabler Länge verwenden. Sie können es in long, int oder short konvertieren, je nachdem, was Ihren Anforderungen entspricht.
oder um die Polarität zu bezeichnen:
Um Bytes zurückzubekommen, einfach:
quelle
Eine grundlegende Implementierung wäre ungefähr so:
Um die Dinge zu verstehen, können Sie diesen WP-Artikel lesen: http://en.wikipedia.org/wiki/Endianness
Der obige Quellcode wird ausgegeben
34 12 78 56 bc 9a
. Die ersten 2 Bytes (34 12
) stellen die erste Ganzzahl usw. dar. Der obige Quellcode codiert Ganzzahlen im Little-Endian-Format.quelle
quelle
Jemand mit einer Anforderung, bei der er aus Bits lesen muss, sagen wir, Sie müssen nur aus 3 Bits lesen, aber Sie benötigen eine vorzeichenbehaftete Ganzzahl und verwenden dann Folgendes:
Die magische Zahl
3
kann durch die Anzahl der von Ihnen verwendeten Bits (nicht Bytes) ersetzt werden.quelle
Wie so oft hat Guave das, was Sie brauchen.
Um vom Byte-Array zu int: zu wechseln
Ints.fromBytesArray
, dokumentieren Sie hierUm von int zu Byte Array zu wechseln :
Ints.toByteArray
, doc hierquelle
Ich denke, dies ist der beste Modus, um auf int zu übertragen
erstes Byte in String konvertieren
Der nächste Schritt ist das Konvertieren in ein Int
aber Byte ist in Wut von -128 bis 127 für diesen Grund, ich denke, ist besser, Wut 0 bis 255 zu verwenden, und Sie müssen nur dies tun:
quelle