HOWTO · Java
Konvertieren Sie Byte-Array in Integer in Java
Dieses Tutorial zeigt, wie man in Java ein Byte-Array in int umwandelt
Auf dieser Seite
Ein Byte-Array in Java in einen int-Wert umzuwandeln, ist eine häufige Aufgabe bei der Arbeit mit Netzwerkprotokollen, Datei-I/O oder binären Datenformaten. Der passende Ansatz hängt davon ab, was die Bytes darstellen: Manchmal codieren mehrere Bytes gemeinsam einen int, manchmal ist jedes Byte ein eigenständiger Wert. Dieser Artikel behandelt die zentralen Java-Methoden — ByteBuffer, DataInputStream, manuelle Bitverschiebung und BigInteger — sowie die Regeln zu Byte-Reihenfolge und Vorzeichen, die darüber entscheiden, ob das Ergebnis korrekt ist.
Vier Bytes mit ByteBuffer in einen int umwandeln
ByteBuffer (in java.nio) ist das direkteste Standard-Java-Werkzeug für diese Umwandlung. Die Methode wrap erzeugt einen Puffer, der sich den Speicher des Arrays teilt, und getInt() liest vier Bytes ab der aktuellen Position des Puffers und interpretiert sie als einen int-Wert. Führen Sie dieses Beispiel aus:
Der Code und die angezeigte Bezeichnung in der Ausgabe bleiben unverändert auf Englisch.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import java.nio.ByteBuffer;
public class ByteArrayToInt {
public static void main(String[] args) {
byte[] byteArray = {0x00, 0x01, 0x03, 0x10};
int intValue = ByteBuffer.wrap(byteArray).getInt();
System.out.println("Converted Integer Value: " + intValue);
}
}
Ausgabe:
Converted Integer Value: 66320
Ein ByteBuffer verwendet auf jeder Plattform standardmäßig Big-Endian: Das erste Byte im Array gilt als höchstwertiges Byte. Wenn die Daten in Little-Endian-Reihenfolge geschrieben wurden, wählen Sie diese Reihenfolge vor dem Lesen explizit mit ByteOrder:
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class ByteArrayToIntOrder {
public static void main(String[] args) {
byte[] byteArray = {0x00, 0x01, 0x03, 0x10};
int bigEndianValue = ByteBuffer.wrap(byteArray).getInt();
int littleEndianValue =
ByteBuffer.wrap(byteArray).order(ByteOrder.LITTLE_ENDIAN).getInt();
System.out.println("big-endian: " + bigEndianValue);
System.out.println("little-endian: " + littleEndianValue);
}
}
Ausgabe:
big-endian: 66320
little-endian: 268632320
Zwei Details sind hier wichtig. Erstens liest getInt() ab der aktuellen Position des Puffers und setzt sie um vier Bytes weiter; ein zweiter Aufruf auf demselben Puffer liest daher die nächsten vier Bytes, und ein neues wrap beginnt immer bei Position 0. Zweitens löst getInt() eine BufferUnderflowException aus, wenn weniger als vier Bytes übrig sind. Prüfen Sie deshalb vor dem Lesen die Länge der Eingabe.
Vier Bytes mit DataInputStream lesen
Wenn die Bytes über einen Stream eintreffen — oder wenn Sie mehrere primitive Werte nacheinander lesen möchten — ist DataInputStream gut geeignet. Verpacken Sie das Array in einen ByteArrayInputStream, diesen wiederum in einen DataInputStream, und rufen Sie readInt() auf:
Der Code und die angezeigte Bezeichnung in der Ausgabe bleiben unverändert auf Englisch.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
public class ByteArrayToIntWithDataInputStream {
public static void main(String[] args) throws IOException {
byte[] byteArray = {0x00, 0x01, 0x03, 0x10};
try (DataInputStream input =
new DataInputStream(new ByteArrayInputStream(byteArray))) {
int intValue = input.readInt();
System.out.println("Converted Integer Value: " + intValue);
}
}
}
Ausgabe:
Converted Integer Value: 66320
readInt() interpretiert die nächsten vier Bytes unabhängig von der Plattform immer in Big-Endian-Reihenfolge. Wenn im Stream weniger als vier Bytes übrig sind, löst die Methode eine EOFException aus. Sie können diese Ausnahme abfangen, um eine zu kurze Eingabe zu melden, statt das Programm abstürzen zu lassen; die Meldung im Beispiel bleibt unverändert auf Englisch:
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
public class ByteArrayToIntShortInput {
public static void main(String[] args) throws IOException {
byte[] byteArray = {0x03, 0x10};
try (DataInputStream input =
new DataInputStream(new ByteArrayInputStream(byteArray))) {
int intValue = input.readInt();
System.out.println("Converted Integer Value: " + intValue);
} catch (EOFException e) {
System.out.println("readInt() needs four bytes, but only " + byteArray.length + " remain");
}
}
}
Ausgabe:
readInt() needs four bytes, but only 2 remain
Ein int durch Verschieben von Bytes zusammensetzen
Wenn Sie die Bytes selbst verschieben, wird genau sichtbar, wie die Umwandlung funktioniert, und Sie erhalten die volle Kontrolle über Reihenfolge und Länge. Verschieben Sie für jedes Byte den bisher akkumulierten Wert um 8 Bits nach links und verknüpfen Sie das nächste Byte bitweise mit ODER:
Der Code und die angezeigte Bezeichnung in der Ausgabe bleiben unverändert auf Englisch.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
public class ByteArrayToIntManually {
public static void main(String[] args) {
byte[] byteArray = {0x00, 0x01, 0x03, 0x10};
int intValue = 0;
for (byte b : byteArray) {
intValue = (intValue << 8) | (b & 0xFF);
}
System.out.println("Converted Integer Value: " + intValue);
}
}
Ausgabe:
Converted Integer Value: 66320
Die Maske b & 0xFF ist erforderlich, weil der Java-Typ byte vorzeichenbehaftet ist: 0x80 wird als -128 gespeichert. Ohne die Maske würde | den Wert 0xFFFFFF80 statt 0x00000080 einbeziehen und jedes höherwertige Byte verfälschen. Diese Schleife setzt die Bytes in Big-Endian-Reihenfolge zusammen — das erste Array-Element ist das höchstwertige Byte — und setzt voraus, dass das Array genau vier Bytes enthält. Für eine andere Reihenfolge durchlaufen Sie das Array in umgekehrter Richtung; für mehr Bytes akkumulieren Sie den Wert in einem long statt in einem int.
Ein Byte-Array mit BigInteger interpretieren
BigInteger nimmt im Konstruktor direkt ein Byte-Array entgegen und interpretiert es als vorzeichenbehaftete Big-Endian-Zahl beliebiger Länge im Zweierkomplement. intValue() verengt das Ergebnis anschließend auf einen int:
Der Code und die angezeigte Bezeichnung in der Ausgabe bleiben unverändert auf Englisch.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import java.math.BigInteger;
public class ByteArrayToIntWithBigInteger {
public static void main(String[] args) {
byte[] byteArray = {0x00, 0x01, 0x03, 0x10};
int intValue = new BigInteger(byteArray).intValue();
System.out.println("Converted Integer Value: " + intValue);
}
}
Ausgabe:
Converted Integer Value: 66320
Da die Interpretation vorzeichenbehaftet ist, erzeugt ein führendes 1-Bit einen Wert kleiner als 0. Übergeben Sie für die vorzeichenlose Interpretation den Signum-Wert 1 als erstes Konstruktorargument. Beachten Sie, dass intValue() nur die unteren 32 Bits behält — Werte, die nicht in einen int passen, werden ohne Hinweis abgeschnitten. Die Bezeichnungen in der folgenden Ausgabe bleiben unverändert auf Englisch:
import java.math.BigInteger;
public class BigIntegerSignAndRange {
public static void main(String[] args) {
byte[] allOnes = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
System.out.println("signed: " + new BigInteger(allOnes));
System.out.println("unsigned: " + new BigInteger(1, allOnes));
System.out.println("narrowed to int: " + new BigInteger(1, allOnes).intValue());
}
}
Ausgabe:
signed: -1
unsigned: 4294967295
narrowed to int: -1
BigInteger ist die naheliegende Wahl, wenn das Array länger als vier Bytes ist oder wenn Sie den vorzeichenlosen Betrag vor der Verengung benötigen.
Jedes Byte separat umwandeln
Alle bisherigen Methoden fassen mehrere Bytes zu einer Zahl zusammen. Wenn jedes Byte ein eigenständiger Wert ist — etwa ein Sensormesswert, ein Farbkanal oder ein Protokollfeld — wandeln Sie die Elemente stattdessen einzeln um. Beachten Sie den Unterschied: getShort() oder readShort() erzeugt aus zwei Bytes einen gemeinsamen short-Wert und wandelt nicht jedes Byte separat um.
Denken Sie außerdem daran, dass der Java-Typ byte vorzeichenbehaftet ist und den Bereich von -128 bis 127 abdeckt. Wenn ein vorzeichenloser Wert von 0 bis 255 gemeint ist, verwenden Sie Byte.toUnsignedInt (seit Java 8 verfügbar) oder die gleichwertige Maske b & 0xFF:
Der Code sowie die englischen Bezeichnungen für beide Interpretationen bleiben in der Ausgabe unverändert.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
public class PrintEachByte {
public static void main(String[] args) {
byte[] byteArray = {0x03, 0x04, (byte) 0x80, (byte) 0xFF};
for (byte b : byteArray) {
System.out.println("signed: " + b + " unsigned: " + Byte.toUnsignedInt(b));
}
}
}
Ausgabe:
signed: 3 unsigned: 3
signed: 4 unsigned: 4
signed: -128 unsigned: 128
signed: -1 unsigned: 255
Eine Methode auswählen und Grenzfälle behandeln
Jeder Ansatz eignet sich für eine andere Situation:
ByteBufferist die erste Wahl, um einen Vier-Byte-intaus einem Array zu lesen: Die Methode ist kompakt, unterstützt überByteOrderbeide Byte-Reihenfolgen und bietet mitgetLong(),getShort()und verwandten Methoden auch andere Breiten an.DataInputStreameignet sich für Code, der bereits mit Streams arbeitet und mehrere typisierte Werte nacheinander lesen muss; seine Lesevorgänge sind immer Big-Endian.- Das manuelle Verschieben kostet ein paar Zeilen mehr, steuert aber Reihenfolge, Offset und Breite präzise und benötigt weder ein Puffer- noch ein Stream-Objekt.
BigIntegerverarbeitet Arrays mit mehr als vier Bytes sowie eine explizit vorzeichenbehaftete oder vorzeichenlose Interpretation vor der Verengung.- Die Umwandlung pro Byte mit
Byte.toUnsignedIntist sinnvoll, wenn jedes Element einen eigenen Wert darstellt und nicht Teil einer gemeinsamen Zahl ist.
Unabhängig davon, für welche Methode Sie sich entscheiden, prüfen Sie vor dem Umwandeln diese Punkte:
- Eingabelänge: Ein Vier-Byte-Lesevorgang auf einem kürzeren Array schlägt fehl — mit
BufferUnderflowExceptionbeiByteBuffer,EOFExceptionbeiDataInputStreamund mit einerArrayIndexOutOfBoundsExceptionoder einem stillschweigend falschen Ergebnis bei manuellem Code. - Byte-Reihenfolge: Die Reihenfolge beim Lesen muss zu der Reihenfolge passen, in der die Bytes geschrieben wurden.
ByteBufferverwendet standardmäßig Big-Endian und kann mitByteOrderumgestellt werden, währendDataInputStreamohne Reihenfolgenoption immer Big-Endian liest. - Vorzeichen und Wertebereich:
getInt()undreadInt()geben einen vorzeichenbehaftetenintzurück, sodass ein vorzeichenloser 32-Bit-Wert oberhalb vonInteger.MAX_VALUEkleiner als 0 erscheint. Verwenden SieInteger.toUnsignedLong(intValue)oder akkumulieren Sie den Wert in einemlong, wenn die Quelldaten vorzeichenlos sind. - Pufferposition: Ein wiederverwendeter
ByteBufferliest ab seiner aktuellen Position weiter, nicht ab dem Anfang. Rufen Sierewind()auf oder verwenden Siewraperneut, um das Array erneut zu lesen.