webentwicklung-frage-antwort-db.com.de

Wie konvertiere ich ein Byte-Array in einen String und umgekehrt?

Ich muss ein Bytearray in Android in eine Zeichenfolge konvertieren, aber mein Bytearray enthält negative Werte.

Wenn ich diese Zeichenfolge erneut in ein Byte-Array konvertiere, unterscheiden sich die Werte, die ich erhalte, von den ursprünglichen Byte-Array-Werten.

Was kann ich für eine korrekte Konvertierung tun? Code, den ich für die Konvertierung verwende, lautet wie folgt:

// Code to convert byte arr to str:
byte[] by_original = {0,1,-2,3,-4,-5,6};
String str1 = new String(by_original);
System.out.println("str1 >> "+str1);

// Code to convert str to byte arr:
byte[] by_new = str1.getBytes();
for(int i=0;i<by_new.length;i++) 
System.out.println("by1["+i+"] >> "+str1);

Ich stecke in diesem Problem fest.

193
Jyotsna

Ihr Bytearray muss etwas kodiert sein. Die Kodierung darf nicht ASCII sein, wenn Sie negative Werte haben. Sobald Sie das herausgefunden haben, können Sie eine Menge von Bytes in einen String konvertieren.

byte[] bytes = {...}
String str = new String(bytes, "UTF-8"); // for UTF-8 encoding

Es gibt eine Reihe von Kodierungen, die Sie verwenden können. Schauen Sie sich die Charset-Klasse in den Sun-Javadocs an.

305
omerkudat

Bei der "richtigen Konvertierung" zwischen byte[] und String wird die von Ihnen gewünschte Codierung explizit angegeben. Wenn Sie mit einem byte[] beginnen und er eigentlich keine Textdaten enthält, ist ist nein "richtige Konvertierung". Strings sind für Text, byte[] für binäre Daten, und das einzig wirklich Sinnvolle ist, Vermeiden _ zwischen ihnen zu konvertieren, es sei denn, Sie müssen dies unbedingt tun.

Wenn Sie wirklich eine String verwenden müssen, um binäre Daten zu speichern, ist die sicherste Methode die Verwendung von Base64 coding.

97

Das Grundproblem ist (denke ich), dass Sie unwissentlich einen Zeichensatz verwenden, für den:

 bytes != encode(decode(bytes))

in manchen Fällen. UTF-8 ist ein Beispiel für einen solchen Zeichensatz. Insbesondere sind bestimmte Bytefolgen keine gültigen Kodierungen in UTF-8. Wenn der UTF-8-Decoder auf eine dieser Sequenzen stößt, kann er die fehlerhaften Bytes verwerfen oder als Unicode-Codepunkt für "kein solches Zeichen" dekodieren. Wenn Sie dann versuchen, die Zeichen als Bytes zu codieren, wird das Ergebnis natürlich anders sein.

Die Lösung ist:

  1. Seien Sie explizit über die von Ihnen verwendete Zeichenkodierung. Verwenden Sie also einen String-Konstruktor und eine String.toByteArray-Methode mit einem expliziten Zeichensatz.
  2. Verwenden Sie den richtigen Zeichensatz für Ihre Byte-Daten ... oder alternativ einen (z. B. "Latin-1"), bei dem alle Byte-Sequenzen gültigen Unicode-Zeichen zugeordnet sind.
  3. Wenn Ihre Bytes (wirklich) binäre Daten sind und Sie sie über einen "textbasierten" Kanal senden/empfangen möchten, verwenden Sie eine Base64-Codierung ... die für diesen Zweck entwickelt wurde .
36
Stephen C

Wir müssen nur eine neue String mit dem Array erstellen: http://www.mkyong.com/Java/how-do-convert-byte-array-to-string-in-Java/

String s = new String(bytes);

Die Bytes der resultierenden Zeichenfolge hängen davon ab, welchen Zeichensatz Sie verwenden. Neuer String (Bytes) und neuer String (Bytes, Charset.forName ("utf-8")) und neuer String (Bytes, Charset.forName ("utf-16")) haben beim Aufruf von String # alle unterschiedliche Byte-Arrays getBytes () (abhängig vom Standardzeichensatz) 

29

Die Verwendung von new String(byOriginal) und die Rückwandlung in byte[] mit getBytes() garantiert nicht zwei byte[] mit gleichen Werten. Dies ist auf einen Aufruf vonStringCoding.encode(..)zurückzuführen, der die String inCharset.defaultCharset()codiert. Während dieser Kodierung wählt der Encoder möglicherweise unbekannte Zeichen aus und führt andere Änderungen durch. Daher gibt die Verwendung von String.getBytes() möglicherweise kein gleichwertiges Array zurück, das Sie ursprünglich an den Konstruktor übergeben haben.

12
sfussenegger

Warum war das Problem: Als jemand bereits angegeben hat: Wenn Sie mit einem Byte [] beginnen und es eigentlich keine Textdaten enthält, gibt es keine "richtige Konvertierung". Zeichenfolgen sind für Text, Byte [] für Binärdaten und das einzig wirklich Sinnvolle ist zu vermeiden Konvertierung zwischen ihnen, es sei denn, Sie müssen unbedingt.

Ich habe dieses Problem beobachtet, als ich versuchte, Byte [] aus einer PDF-Datei zu erstellen, es in String umzuwandeln und dann den String als Eingabe zu nehmen und wieder in eine Datei zu konvertieren.  

Stellen Sie daher sicher, dass Ihre Codierungs- und Decodierungslogik dieselbe ist wie ich. Ich habe das Byte [] explizit in Base64 codiert und decodiert, um die Datei erneut zu erstellen.

Use-Case: Aufgrund einiger Einschränkungen versuchte ich, byte[] in request(POST) zu senden, und der Vorgang war wie folgt:

PDF Datei >> Base64.encodeBase64 (byte []) >> String >> Anfrage senden (POST) >> receive String >> Base64.decodeBase64 (byte []) >> binär erstellen

Versuchen Sie das und das hat für mich funktioniert ..

File file = new File("filePath");

        byte[] byteArray = new byte[(int) file.length()];

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            fileInputStream.read(byteArray);

            String byteArrayStr= new String(Base64.encodeBase64(byteArray));

            FileOutputStream fos = new FileOutputStream("newFilePath");
            fos.write(Base64.decodeBase64(byteArrayStr.getBytes()));
            fos.close();
        } 
        catch (FileNotFoundException e) {
            System.out.println("File Not Found.");
            e.printStackTrace();
        }
        catch (IOException e1) {
            System.out.println("Error Reading The File.");
            e1.printStackTrace();
        }
9
Rupesh

Das funktioniert gut für mich:

String cd="Holding some value";

Konvertierung von String in Byte []:

byte[] cookie = new Sun.misc.BASE64Decoder().decodeBuffer(cd);

Konvertierung von Byte [] in String:

cd = new Sun.misc.BASE64Encoder().encode(cookie);
6
LeD
private static String toHexadecimal(byte[] digest){
        String hash = "";
    for(byte aux : digest) {
        int b = aux & 0xff;
        if (Integer.toHexString(b).length() == 1) hash += "0";
        hash += Integer.toHexString(b);
    }
    return hash;
}
5
sdelvalle57

Ich habe etwas bemerkt, das in keiner der Antworten vorkommt. Sie können jedes Byte im Byte-Array in Zeichen umwandeln und sie in ein Zeichen-Array einfügen. Dann ist die Zeichenfolge

new String(cbuf)

public class StringByteArrTest {

    public static void main(String[] args) {
        // put whatever byte array here
        byte[] arr = new byte[] {-12, -100, -49, 100, -63, 0, -90};
        for (byte b: arr) System.out.println(b);
        // put data into this char array
        char[] cbuf = new char[arr.length];
        for (int i = 0; i < arr.length; i++) {
            cbuf[i] = (char) arr[i];
        }
        // this is the string
        String s = new String(cbuf);
        System.out.println(s);

        // converting back
        byte[] out = new byte[s.length()];
        for (int i = 0; i < s.length(); i++) {
            out[i] = (byte) s.charAt(i);
        }
        for (byte b: out) System.out.println(b);
    }

}

5
Leonid

javax.xml.bind.DatatypeConverter sollte es tun:

byte [] b = javax.xml.bind.DatatypeConverter.parseHexBinary("E62DB");
String s = javax.xml.bind.DatatypeConverter.printHexBinary(b);
2

Hier einige Methoden, die ein Byte-Array in einen String umwandeln. Ich habe sie getestet, sie funktionieren gut.

public String getStringFromByteArray(byte[] settingsData) {

    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(settingsData);
    Reader reader = new BufferedReader(new InputStreamReader(byteArrayInputStream));
    StringBuilder sb = new StringBuilder();
    int byteChar;

    try {
        while((byteChar = reader.read()) != -1) {
            sb.append((char) byteChar);
        }
    }
    catch(IOException e) {
        e.printStackTrace();
    }

    return sb.toString();

}

public String getStringFromByteArray(byte[] settingsData) {

    StringBuilder sb = new StringBuilder();
    for(byte willBeChar: settingsData) {
        sb.append((char) willBeChar);
    }

    return sb.toString();

}
2
user2288580

Während die base64-Verschlüsselung sicher ist und man die "richtige Antwort" argumentieren könnte, bin ich hier angekommen, auf der Suche nach einer Möglichkeit, ein Java-Byte-Array in/aus einem Java-String zu konvertieren, wie er ist. Das heißt, wenn jedes Mitglied des Byte-Arrays in seinem String-Gegenstück intakt bleibt und kein zusätzlicher Speicherplatz für das Codieren/Transportieren erforderlich ist.

Diese Antwort 8bit transparente Kodierungen zu beschreiben war sehr hilfreich für mich. Ich habe ISO-8859-1 für Terabytes von Binärdaten verwendet, um erfolgreich hin und her zu konvertieren (binärer <-> String), ohne den für eine base64-Codierung erforderlichen überhöhten Speicherplatzbedarf. Daher ist dies für meinen Anwendungsfall - YMMV - sicher.

Dies war auch hilfreich um zu erklären, wann/ob Sie experimentieren sollten.

1
Reed Sandberg

Es ist mir gelungen, Byte-Array mit dieser Methode in einen String zu konvertieren:

public static String byteArrayToString(byte[] data){
    String response = Arrays.toString(data);

    String[] byteValues = response.substring(1, response.length() - 1).split(",");
    byte[] bytes = new byte[byteValues.length];

    for (int i=0, len=bytes.length; i<len; i++) {
        bytes[i] = Byte.parseByte(byteValues[i].trim());
    }

    String str = new String(bytes);
    return str.toLowerCase();
}
1
lxknvlk

Ereignis obwohl 

new String(bytes, "UTF-8")

ist korrekt, wirft eine UnsupportedEncodingException, die Sie zwingt, mit einer geprüften Ausnahme umzugehen. Sie können alternativ einen anderen Konstruktor seit Java 1.6 verwenden, um ein Byte-Array in eine String-Datei zu konvertieren:

new String(bytes, StandardCharsets.UTF_8)

Dieser löst keine Ausnahme aus.

Rückkonvertierung sollte auch mit StandardCharsets.UTF_8 erfolgen:

"test".getBytes(StandardCharsets.UTF_8)

Wiederum vermeiden Sie es, mit geprüften Ausnahmen umzugehen.

0
gil.fernandes
import Sun.misc.BASE64Decoder;
import Sun.misc.BASE64Encoder;    

private static String base64Encode(byte[] bytes)
{
    return new BASE64Encoder().encode(bytes);
}

private static byte[] base64Decode(String s) throws IOException
{
    return new BASE64Decoder().decodeBuffer(s);
}
0
Feng Zhang