Konvertieren Sie String in Byte Array und Reverse in Java

1. Einleitung

In Java müssen wir häufig zwischen String und Byte- Array konvertieren . In diesem Tutorial werden wir diese Vorgänge im Detail untersuchen.

Zunächst werden verschiedene Möglichkeiten zum Konvertieren eines Strings in ein Byte- Array untersucht. Dann werden wir ähnliche Operationen in umgekehrter Reihenfolge betrachten.

2. Konvertieren eines Strings in ein Byte- Array

Ein String wird in Java als Array von Unicode-Zeichen gespeichert. Um es in ein Byte- Array umzuwandeln , übersetzen wir die Zeichenfolge in eine Folge von Bytes. Für diese Übersetzung verwenden wir eine Instanz von Charset . Diese Klasse gibt eine Zuordnung zwischen einer Abfolge von char s und einer Folge von Byte - s .

Wir bezeichnen den obigen Prozess als Codierung .

Wir können einen String in Java auf verschiedene Arten in ein Byte- Array codieren . Schauen wir uns jeden einzelnen anhand von Beispielen genauer an.

2.1. Verwenden von String.getBytes ()

Die String - Klasse enthält drei überladene getBytes Methoden einen kodieren String in einen Byte - Array :

  • getBytes () - Codiert mit dem Standardzeichensatz der Plattform
  • getBytes (String charsetName) - Codiert mit dem benannten Zeichensatz
  • getBytes (Zeichensatz-Zeichensatz) - Codiert mit dem angegebenen Zeichensatz

Zunächst werfen wir einen String mit der Plattform Standard - charset kodieren:

String inputString = "Hello World!"; byte[] byteArrray = inputString.getBytes();

Die obige Methode ist plattformabhängig, da sie den Standardzeichensatz der Plattform verwendet. Wir können diesen Zeichensatz erhalten, indem wir Charset.defaultCharset () aufrufen .

Zweitens codieren wir eine Zeichenfolge mit einem benannten Zeichensatz:

@Test public void whenGetBytesWithNamedCharset_thenOK() throws UnsupportedEncodingException { String inputString = "Hello World!"; String charsetName = "IBM01140"; byte[] byteArrray = inputString.getBytes("IBM01140"); assertArrayEquals( new byte[] { -56, -123, -109, -109, -106, 64, -26, -106, -103, -109, -124, 90 }, byteArrray); }

Diese Methode löst eine UnsupportedEncodingException aus, wenn der angegebene Zeichensatz nicht unterstützt wird.

Das Verhalten der beiden oben genannten Versionen ist undefiniert, wenn die Eingabe Zeichen enthält, die vom Zeichensatz nicht unterstützt werden. Im Gegensatz dazu verwendet die dritte Version das Standard-Ersatzbyte-Array des Zeichensatzes, um nicht unterstützte Eingaben zu codieren.

Rufen Sie als Nächstes die dritte Version der Methode getBytes () auf und übergeben Sie eine Instanz von Charset:

@Test public void whenGetBytesWithCharset_thenOK() { String inputString = "Hello ਸੰਸਾਰ!"; Charset charset = Charset.forName("ASCII"); byte[] byteArrray = inputString.getBytes(charset); assertArrayEquals( new byte[] { 72, 101, 108, 108, 111, 32, 63, 63, 63, 63, 63, 33 }, byteArrray); }

Hier verwenden wir den Factory - Methode Charset.forName eine Instanz der bekommen Charset . Diese Methode löst eine Laufzeitausnahme aus, wenn der Name des angeforderten Zeichensatzes ungültig ist. Es wird auch eine Laufzeitausnahme ausgelöst, wenn der Zeichensatz in der aktuellen JVM unterstützt wird.

Einige Zeichensätze sind jedoch garantiert auf jeder Java-Plattform verfügbar. Die StandardCharsets- Klasse definiert Konstanten für diese Zeichensätze.

Zum Schluss codieren wir mit einem der Standardzeichensätze:

@Test public void whenGetBytesWithStandardCharset_thenOK() { String inputString = "Hello World!"; Charset charset = StandardCharsets.UTF_16; byte[] byteArrray = inputString.getBytes(charset); assertArrayEquals( new byte[] { -2, -1, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 100, 0, 33 }, byteArrray); }

Damit schließen wir die Überprüfung der verschiedenen getBytes- Versionen ab. Schauen wir uns als nächstes die von Charset selbst bereitgestellte Methode an .

2.2. Verwenden von Charset.encode ()

Die Charset- Klasse bietet encode () , eine praktische Methode, die Unicode-Zeichen in Bytes codiert. Diese Methode ersetzt immer ungültige Eingaben und nicht zuordnungsfähige Zeichen mithilfe des Standard-Ersatzbyte-Arrays des Zeichensatzes.

Verwenden wir die encode- Methode, um einen String in ein Byte- Array zu konvertieren :

@Test public void whenEncodeWithCharset_thenOK() { String inputString = "Hello ਸੰਸਾਰ!"; Charset charset = StandardCharsets.US_ASCII; byte[] byteArrray = charset.encode(inputString).array(); assertArrayEquals( new byte[] { 72, 101, 108, 108, 111, 32, 63, 63, 63, 63, 63, 33 }, byteArrray); }

Wie wir oben sehen können, haben nicht unterstützte Zeichen mit dem Standard Ersatz des charset ersetzt Byte 63.

Die bisher verwendeten Ansätze verwenden die CharsetEncoder- Klasse intern, um die Codierung durchzuführen. Lassen Sie uns diese Klasse im nächsten Abschnitt untersuchen.

2.3. CharsetEncoder

CharsetEncoder wandelt Unicode-Zeichen in eine Folge von Bytes für einen bestimmten Zeichensatz um . Darüber hinaus bietet es eine fein abgestimmte Kontrolle über den Codierungsprozess .

Verwenden wir diese Klasse, um einen String in ein Byte- Array zu konvertieren :

@Test public void whenUsingCharsetEncoder_thenOK() throws CharacterCodingException { String inputString = "Hello ਸੰਸਾਰ!"; CharsetEncoder encoder = StandardCharsets.US_ASCII.newEncoder(); encoder.onMalformedInput(CodingErrorAction.IGNORE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .replaceWith(new byte[] { 0 }); byte[] byteArrray = encoder.encode(CharBuffer.wrap(inputString)) .array(); assertArrayEquals( new byte[] { 72, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 33 }, byteArrray); }

Hier erstellen wir eine Instanz von CharsetEncoder, indem wir die newEncoder- Methode für ein Charset- Objekt aufrufen .

Anschließend geben wir Aktionen für Fehlerbedingungen an, indem wir die Methoden onMalformedInput () und onUnmappableCharacter () aufrufen . Wir können die folgenden Aktionen angeben:

  • IGNORE - Löschen Sie die fehlerhafte Eingabe
  • ERSETZEN - Ersetzen Sie die fehlerhafte Eingabe
  • REPORT - Melden Sie den Fehler, indem Sie ein CoderResult- Objekt zurückgeben oder eine CharacterCodingException auslösen

Außerdem verwenden wir den replaceWith () Methode den Ersatz zu spezifizieren Byte - Array.

Daher schließen wir die Überprüfung verschiedener Ansätze zum Konvertieren eines Strings in ein Byte-Array ab. Schauen wir uns als nächstes die umgekehrte Operation an.

3. Konvertieren des Byte-Arrays in einen String

Wir bezeichnen den Prozess des Konvertierens eines Byte- Arrays in einen String als Decodierung . Ähnlich wie beim Codieren erfordert dieser Prozess einen Zeichensatz .

Wir können jedoch nicht einfach einen Zeichensatz zum Decodieren eines Byte-Arrays verwenden. Wir sollten den Zeichensatz verwenden, der zum Codieren des Strings in das Byte- Array verwendet wurde .

Wir können ein Byte-Array auf viele Arten in einen String konvertieren. Lassen Sie uns jeden von ihnen im Detail untersuchen.

3.1. Verwenden des String- Konstruktors

The String class has few constructors which take a byte array as input. They are all similar to the getBytes method but work in reverse.

First, let's convert a byte array to String using the platform's default charset:

@Test public void whenStringConstructorWithDefaultCharset_thenOK() { byte[] byteArrray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 }; String string = new String(byteArrray); assertNotNull(string); }

Note that we don't assert anything here about the contents of the decoded string. This is because it may decode to something different, depending on the platform's default charset.

For this reason, we should generally avoid this method.

Secondly, let's use a named charset for decoding:

@Test public void whenStringConstructorWithNamedCharset_thenOK() throws UnsupportedEncodingException { String charsetName = "IBM01140"; byte[] byteArrray = { -56, -123, -109, -109, -106, 64, -26, -106, -103, -109, -124, 90 }; String string = new String(byteArrray, charsetName); assertEquals("Hello World!", string); }

This method throws an exception if the named charset is not available on the JVM.

Thirdly, let's use a Charset object to do decoding:

@Test public void whenStringConstructorWithCharSet_thenOK() { Charset charset = Charset.forName("UTF-8"); byte[] byteArrray = { 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33 }; String string = new String(byteArrray, charset); assertEquals("Hello World!", string); }

Finally, let's use a standard Charset for the same:

@Test public void whenStringConstructorWithStandardCharSet_thenOK() { Charset charset = StandardCharsets.UTF_16; byte[] byteArrray = { -2, -1, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, 87, 0, 111, 0, 114, 0, 108, 0, 100, 0, 33 }; String string = new String(byteArrray, charset); assertEquals("Hello World!", string); }

So far, we have converted a byte array into a String using the constructor. Let's now look into the other approaches.

3.2. Using Charset.decode()

The Charset class provides the decode() method that converts a ByteBuffer to String:

@Test public void whenDecodeWithCharset_thenOK() { byte[] byteArrray = { 72, 101, 108, 108, 111, 32, -10, 111, 114, 108, -63, 33 }; Charset charset = StandardCharsets.US_ASCII; String string = charset.decode(ByteBuffer.wrap(byteArrray)) .toString(); assertEquals("Hello �orl�!", string); }

Here, the invalid input is replaced with the default replacement character for the charset.

3.3. CharsetDecoder

Alle vorherigen Ansätze zum internen Decodieren verwenden die CharsetDecoder- Klasse. Wir können diese Klasse direkt zur detaillierten Steuerung des Dekodierungsprozesses verwenden :

@Test public void whenUsingCharsetDecoder_thenOK() throws CharacterCodingException { byte[] byteArrray = { 72, 101, 108, 108, 111, 32, -10, 111, 114, 108, -63, 33 }; CharsetDecoder decoder = StandardCharsets.US_ASCII.newDecoder(); decoder.onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .replaceWith("?"); String string = decoder.decode(ByteBuffer.wrap(byteArrray)) .toString(); assertEquals("Hello ?orl?!", string); }

Hier ersetzen wir ungültige Eingaben und nicht unterstützte Zeichen durch "?".

Wenn wir über ungültige Eingaben informiert werden möchten, können wir den Decoder wie folgt ändern :

decoder.onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT)

4. Fazit

In diesem Artikel haben wir mehrere Möglichkeiten untersucht, um String in ein Byte-Array zu konvertieren und umzukehren. Wir sollten die geeignete Methode basierend auf den Eingabedaten sowie dem für ungültige Eingaben erforderlichen Kontrollniveau auswählen.

Wie immer finden Sie den vollständigen Quellcode auf GitHub.