2016-06-22 9 views
2

Ich habe eine Byte-Array über eine Netzwerkverbindung gelesen, die ich in eine Zeichenfolge ohne Codierung, dh einfach durch Behandlung jedes Byte als das untere Ende eines Zeichens und Verlassen der oberen Nullstelle. Ich muss auch das Gegenteil tun, wo ich weiß, dass das obere Ende des Charakters immer Null ist.Konvertieren String in/aus Byte-Array ohne Codierung

Die Suche im Internet führt zu mehreren ähnlichen Fragen, bei denen alle Antworten darauf hinweisen, dass die ursprüngliche Datenquelle geändert werden muss. Dies ist keine Option, also bitte nicht vorschlagen.

Dies ist in C trivial, aber Java scheint zu erfordern, dass ich eine eigene Konvertierungsroutine schreibe, die wahrscheinlich sehr ineffizient ist. Gibt es einen leichten Weg, den ich verpasst habe?

+0

'neue Zeichenfolge (yourByteArray);'? – tkausl

+0

Wie haben Sie festgestellt, dass es wahrscheinlich sehr ineffizient wäre? – Kayaman

+1

Warum zu einem String konvertieren? Wenn du ein Byte [] hast, könntest du es so lassen wie es ist? Wenn Sie die Codierung nicht kennen, wie könnten Sie diese Bytes dann als String interpretieren wollen? –

Antwort

0

Hier ist ein Beispielcode, der String zu byte array und zurück zu String ohne Codierung umwandeln wird.

public class Test 
{ 

    public static void main(String[] args) 
    { 
     Test t = new Test(); 
     t.Test(); 
    } 

    public void Test() 
    { 
     String input = "Hèllo world"; 
     byte[] inputBytes = GetBytes(input); 
     String output = GetString(inputBytes); 
     System.out.println(output); 
    } 

    public byte[] GetBytes(String str) 
    { 
     char[] chars = str.toCharArray(); 
     byte[] bytes = new byte[chars.length * 2]; 
     for (int i = 0; i < chars.length; i++) 
     { 
      bytes[i * 2] = (byte) (chars[i] >> 8); 
      bytes[i * 2 + 1] = (byte) chars[i]; 
     } 

     return bytes; 
    } 

    public String GetString(byte[] bytes) 
    { 
     char[] chars = new char[bytes.length/2]; 
     char[] chars2 = new char[bytes.length/2]; 
     for (int i = 0; i < chars2.length; i++) 
      chars2[i] = (char) ((bytes[i * 2] << 8) + (bytes[i * 2 + 1] & 0xFF)); 

     return new String(chars2); 

    } 
} 
+0

Danke für die Vorschläge. Ich habe etwas in der Nähe implementiert und alles scheint gut zu funktionieren. –

+0

Können Sie bitte die Antwort akzeptieren, wenn es hilft. – PVR

+0

Dies verwendet zwei Bytes pro char obwohl ... – tkausl

0

Dies konvertiert ein Byte-Array in einen String, während nur die oberen 8 Bits gefüllt werden.

public static String stringFromBytes(byte byteData[]) { 
    char charData[] = new char[byteData.length]; 
    for(int i = 0; i < charData.length; i++) { 
     charData[i] = (char) (((int) byteData[i]) & 0xFF); 
    } 
    return new String(charData); 
} 

Die Effizienz sollte ziemlich gut sein. Wie Ben Thurley sagte, wenn Leistung wirklich ein solches Problem ist, konvertieren sie nicht zu einem String, sondern arbeiten stattdessen mit dem Byte-Array.

0

Zeichenfolge ist bereits als Unicode/UTF-16 codiert. UTF-16 bedeutet, dass bis zu 2 Zeichenfolgen (char) benötigt werden, um ein anzeigbares Zeichen zu erstellen. Was Sie wirklich wollen, ist:

byte[] bytes = System.Text.Encoding.Unicode.GetBytes(myString); 

, um eine Zeichenfolge in ein Array von Bytes zu konvertieren. Dies macht genau das, was Sie oben gemacht haben, außer dass es 10 mal schneller in der Leistung ist. Wenn Sie die Übertragungsdaten mögen fast in zwei Hälften geschnitten, würde ich empfehlen, es zu UTF8 (ASCII eine Teilmenge von UTF-8 ist) - das Format des Internet 90% der Zeit verwendet, durch den Aufruf:

byte[] bytes = Encoding.UTF8.GetBytes(myString); 

zur Umwandlung in einen String Einsatz zurück:

String myString = Encoding.Unicode.GetString(bytes); 

oder

+0

Beachten Sie die Tags. Dieser Code ist für C# /. NET, aber die Frage ist mit [java] getaggt. Dasselbe gilt, und die Bibliotheken sind ähnlich. Willkommen bei Stack Overflow. –

0

Nein, Sie verpassen nichts. Es gibt keine einfache Möglichkeit, das zu tun, weil String und char für Text sind. Offensichtlich möchten Sie Ihre Daten nicht als Text behandeln - was völlig Sinn machen würde, wenn es sich nicht um Text handelt. Sie könnten es auf die harte Art tun, die Sie vorschlagen.

Eine Alternative ist eine Zeichencodierung, die beliebige Sequenzen beliebiger Bytewerte (0-255) zulässt. ISO-8859-1 oder IBM437 sind beide qualifiziert. (Windows-1252 hat nur 251 Codepoints. UTF-8 lässt keine willkürlichen Sequenzen zu.) Wenn Sie ISO-8859-1 verwenden, entspricht die resultierende Zeichenfolge Ihrem harten Weg.

Aus Effizienzgründen ist es am effizientesten, ein Byte-Array als Byte-Array zu verwalten.