String in Byte-Array konvertieren und in Java umkehren

1. Einleitung

Wir müssen häufig zwischen String und byte Array in Java konvertieren.

In diesem Lernprogramm werden diese Operationen ausführlich beschrieben.

Zuerst betrachten wir verschiedene Möglichkeiten, um einen String in ein byte -Array zu konvertieren. Dann werden wir ähnliche Vorgänge in umgekehrter Reihenfolge betrachten.

  1. Konvertieren von String in Byte Array

Ein String wird in Java als Array von Unicode-Zeichen gespeichert. Um es in ein byte -Array zu konvertieren, ü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 Folge von __char s und einer Folge von byte __s ** an.

Wir bezeichnen den obigen Prozess als encoding .

Wir können einen String in Java auf verschiedene Weise in ein byte -Array kodieren.

Lassen Sie uns jeden einzelnen detailliert mit Beispielen betrachten.

2.1. String.getBytes () verwenden

(String charsetName) ]- kodiert mit dem angegebenen Zeichensatz ** https://docs.oracle.com/javase/10/docs/api/java/lang/String.html#getBytes(java.nio.charset.Charset )[ getBytes

(Zeichensatz charset) __]- kodiert mit dem bereitgestellten Zeichensatz

Erstens: Lassen Sie uns eine Zeichenfolge mit dem Standardzeichensatz der Plattform 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 Sie Charset.defaultCharset () aufrufen.

Zweitens, lassen Sie uns einen String mit einem benannten Zeichensatz kodieren:

@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 gibt UnsupportedEncodingException aus, wenn der angegebene Zeichensatz nicht unterstützt wird.

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

Als Nächstes rufen wir die dritte Version von the getBytes () und rufen eine Instanz von __Charset auf:

@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 die Factory-Methode Charset.forName Holen Sie sich eine Instanz des Charset . Diese Methode löst eine Laufzeitausnahme aus, wenn der Name des angeforderten Zeichensatzes ungültig ist. Es wird außerdem eine Laufzeitausnahme ausgelöst, wenn der Zeichensatz in der aktuellen JVM unterstützt wird.

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

Zum Schluss lassen Sie uns mit einem der Standardzeichensätze kodieren:

@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);
}

Somit schließen wir die Überprüfung der verschiedenen getBytes -Versionen ab. Als Nächstes wollen wir uns die Methode ansehen, die von Charset selbst bereitgestellt wird.

2.2. Charset.encode () verwenden

  • Die Klasse Charset stellt encode () zur Verfügung, eine bequeme Methode, die Unicode-Zeichen in Bytes codiert. ** Diese Methode ersetzt immer ungültige Eingabe- und nichtzuordnungsfähige Zeichen mithilfe des Standardersatzbyte-Arrays des Zeichensatzes.

  • Verwenden Sie 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, wurden nicht unterstützte Zeichen durch den Standardersatz byte des Zeichensatzes ersetzt.

Die bisher verwendeten Ansätze verwenden intern die Klasse CharsetEncoder , um die Codierung durchzuführen. Untersuchen wir diese Klasse im nächsten Abschnitt.

2.3. CharsetEncoder

  • CharsetEncoder wandelt Unicode-Zeichen für einen gegebenen Zeichensatz in eine Folge von Bytes um . Darüber hinaus bietet es eine genaue Kontrolle über den Kodierungsprozess. **

Verwenden Sie 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 Methode _newEncoder für ein Charset_ -Objekt aufrufen.

Dann geben wir Aktionen für Fehlerbedingungen an, indem wir onMalformedInput () und __onUnmappableCharacter () methods aufrufen. __Wir können die folgenden Aktionen festlegen:

  • IGNORE - verwirft die fehlerhafte Eingabe

  • REPLACE - Ersetzen Sie die fehlerhafte Eingabe

  • REPORT - Melden Sie den Fehler, indem Sie a zurückgeben

Darüber hinaus verwenden wir die replaceWith () -Methode, um das ersetzte byte -Array anzugeben.

Daher schließen wir die Überprüfung verschiedener Ansätze zum Konvertieren eines Strings in ein Byte-Array ab. Lass uns als nächstes den umgekehrten Vorgang betrachten.

3. Byte-Array in String konvertieren

  • Wir bezeichnen den Prozess der Umwandlung eines byte -Arrays in einen String als decoding ** . Ähnlich wie bei der Codierung erfordert dieser Prozess ein Charset .

Wir können jedoch nicht einfach einen Zeichensatz zum Decodieren eines Byte-Arrays verwenden. Wir sollten den Zeichensatz verwenden, mit dem der String in das byte -Array codiert 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

  • Die String -Klasse hat wenige Konstruktoren, die ein byte -Array als Eingabe verwenden ** . Sie sind alle der Methode getBytes ähnlich, arbeiten jedoch in umgekehrter Reihenfolge.

Zuerst konvertieren Sie ein Byte-Array in String , indem Sie den Standardzeichensatz der Plattform verwenden:

@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);
}
  • Beachten Sie, dass wir hier keine Angaben zum Inhalt der decodierten Zeichenfolge machen. Dies liegt daran, dass je nach Standard-Zeichensatz der Plattform möglicherweise etwas anderes dekodiert wird. **

Aus diesem Grund sollten wir diese Methode generell vermeiden.

Zweitens verwenden zum Dekodieren einen benannten Zeichensatz:

@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);
}

Diese Methode löst eine Ausnahme aus, wenn der benannte Zeichensatz in der JVM nicht verfügbar ist.

Drittens verwenden wir ein Charset -Objekt zum Dekodieren: **

@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);
}

Schließlich verwenden wir ein Standard- Charset für dasselbe: **

@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);
}

Bisher haben wir ein byte -Array mit dem Konstruktor in einen String umgewandelt. Schauen wir uns nun die anderen Ansätze an.

3.2. Charset.decode () verwenden

Die Klasse Charset stellt die Methode decode () bereit, mit der ein ByteBuffer in String konvertiert wird:

@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);
}

Hier wird die ungültige Eingabe durch das Standardersatzzeichen für den Zeichensatz ersetzt.

3.3. CharsetDecoder

Alle bisherigen Ansätze zum internen Decodieren verwenden die Klasse CharsetDecoder .

  • Wir können diese Klasse direkt verwenden, um den Decodierungsprozess fein zu steuern ** :

@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 bei ungültigen Eingaben informiert werden möchten, können wir den decoder ändern als:

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

4. Schlussfolgerung

In diesem Artikel haben wir mehrere Möglichkeiten zum Konvertieren von String in ein Byte-Array und umgekehrt untersucht. Wir sollten die geeignete Methode auf der Grundlage der Eingabedaten sowie des für ungültige Eingaben erforderlichen Kontrollniveaus wählen.

Wie üblich ist der vollständige Quellcode over auf GitHub