Bei einem Strom von Bytes kann seine tatsächliche Bedeutung nicht ohne Angabe seiner Codierung bekannt sein.
Dieser Satz sollte auch das sein, was wir uns immer in unseren Köpfen erinnern, wenn wir uns mit dem Problem des "Charakters zu Byte, Byte zu Charakter" stellen. Andernfalls können verstümmelte Probleme folgen.
Tatsächlich ist die Essenz des verstümmelten Problems, dass Codierung und Dekodierung nicht die gleiche Codierung verwenden. Wenn Sie dieses Prinzip verstehen, ist es leicht, das verstümmte Problem zu lösen.
In Java häufig verwendet werden wie folgt:
1. Die String -Klasse verwendet die Konstruktor -Zeichenfolge (Byte [] Bytes) von Byte []. Die String -Klasse bietet zwei Überladungen zur gleichen Zeit (1) String (Byte [] Bytes, charSet charSet)
(2) String (Byte [] Bytes, String charSetName) wird verwendet, um die Codierung anzugeben.
2. Das GetBytes -Funktions Byte [] getBytes () der String -Klasse hat auch die folgenden zwei Überladungen:
(1) BYTE [] GETBYTES (CHARSET CHARSET)
(2) Byte [] GetBytes (String charSetName)
Alles, was die angegebene Codierung nicht erfordert, wird mithilfe des Standard -Zeichensatzes der Plattform erhalten, das mit System.getProperty ("Datei.encoding"), charSet.DefaultCharSet () erhalten werden kann.
3. PrintStreams Print (String S) ist ebenfalls für dieses Problem ausgelegt. Aus diesem Grund ist der Konstruktor von Printstream nicht nur Printstream (Dateidatei) und Printstream (Dateidatei, Zeichenfolge CSN).
Andernfalls werden die Zeichen der String gemäß der Standardzeichenkodierung der Plattform in Bytes konvertiert.
DataOutputStream -Konstruktion verfügt nicht über eine Methode zum Angeben der Codierung, bietet jedoch ein WriteUTF (String Str)
Geben Sie die Beispiele am Anfang an, um die Notwendigkeit der Angabe der Codierung zu veranschaulichen:
Wenn eine Webseite die Codierung als UTF-8 angibt, <meta http-äquiv = "content-type" content = "text /html; charset = utf-8" /> gibt es ein Formular auf der Seite, das an ein Servlet eingereicht wurde
Anschließend wird der vom Benutzer eingegebene Byte -Stream gemäß der angegebenen Codierung codiert. Wenn Sie beispielsweise "Hallo Hallo" eingeben, wenn es UTF-8 ist, ist das übertragene wie folgt:
[104, 101, 108, 108, 111, -28, -67, -96, -27, -91, -67]
Wir sehen, dass jedes der folgenden chinesischen Zeichen 3 Bytes verwendet, die verwendet werden können, um sich auf die relevante Kenntnisse von UTF-8 zu beziehen.
Wenn Ihre Seite jedoch GBK angibt, ist das Getriebe unterschiedlich:
[104, 101, 108, 108, 111, -60, -29, -70, -61]
Bei Verwendung von Request.GetParameter auf der Servlet -Seite sollte dies daher intern aufgerufen werden
String S = New String (Bytes, Response.GeteCoding ()). Wenn Ihre Antwort die Codierung nicht festlegt, wird die Standard -Codierungsnull für die Java -Plattform in GBK konvertiert, und dann werden die Chinesen verstümmelt.
Um verstümmelten Code zu vermeiden, setzen JSP -Websites im Allgemeinen einen Filter fest, und alle Seiten und Diener sind so eingestellt, dass sie eine einheitliche Codierung haben. response.seteCoding, request.setEncoding.
In der Java-String befindet sich ein Zeichen [], ein Einheit, das mit 16-Bit-gespeicherter UTF-16 codiert ist. Zu diesem Zweck müssen Sie beim Konvertieren von Zeichen und Zeichenfolgen in Bytes und in Dateien oder Netzwerken oder die Rückkehr von Byte -Streams, die aus Dateien oder Netzwerken zu Zeichen mit praktischer Bedeutung gelesen werden, ausgeben, müssen Sie verstehen, was ihre Codierung ist.
Einige Erfahrungen
1. Die String -Klasse wird immer in der Unicode -Codierung gespeichert.
2. Achten Sie auf die Verwendung von String.getBytes ():
Wenn der Charakter -Set -Parameter nicht enthalten ist, hängt er von der Charakter -Set -Codierung des JVM ab. Es ist im Allgemeinen Unicode unter Linux und GBK unter Windows. (Wenn Sie die Decodierung des Standardzeichens -Sets des JVM ändern möchten, verwenden Sie die Option -dFile.encoding = utf -8 beim Starten der JVM.
Aus Sicherheitsgründen wird empfohlen, immer mit Parametern aufzurufen, zum Beispiel: String S; S.GEBYTES ("UTF-8").
3. Die Charset -Klasse ist sehr nützlich.
(1) charSet.encode ist codierend, dh die Zeichenfolge im Zeichensatz -Codierungsformat, das Sie angeben und ein Byte -Array ausgeben.
(2) charSet.decode ist decodieren, dh ein Byte -Array im Zeichen -Codierungsformat, das Sie angeben, dekodieren und in eine Zeichenfolge ausgeben.
Als Beispiel:
String S = charSet.DefaultCharSet (). DisplayName (); String S1 = "Ich mag dich, meine Liebe"; Bytebuffer bb1 = bytebuffer.wrap (s1.getBytes ("utf-8")); für (byte bt: bb1.array ()) {System.out.printf ("%x", bt); } // char [] useage char [] charray = {'i', 'l', 'o', 'v', 'e', 'du'}; // Charbuffer -Nutzung Charbuffer CB = Charbuffer.Wrap (Charray); // Zeiger cb.flip () neu positionieren; String S2 = New String (charray); // bytebuffer useage bytebuffer bb2 = charset.forname ("utf-8"). Code (cb); // charSet verwenden, um als angegebenes Zeichen Set byteBuffer bb3 = charset.forname ("utf-8"). Encode (S1); byte [] b = bb3.Array (); // charSet verwenden, um als Zeichenfolge entsprechend dem angegebenen Zeichensatz Bytebuffer bb4 = bytebuffer.wrap (b) zu dekodieren; String s2 = charSet.forname ("utf-8"). Decode (BB4) .ToString ();