ByteBuffer, CharBuffer, String und Charset
Ich versuche zu Sortieren, Charaktere, deren Darstellung in byte-Sequenzen nach Zeichen setzt, und wie die Konvertierung von einem Zeichensatz zu einem anderen in Java. Ich habe einige Schwierigkeiten.
Beispielsweise
ByteBuffer bybf = ByteBuffer.wrap("Olé".getBytes());
Mein Verständnis ist, dass:
- String werden immer gespeichert als UTF-16-byte-Sequenz in Java (2 bytes pro Zeichen, big endian)
getBytes()
Ergebnis ist das gleiche UTF-16-byte-Sequenzwrap()
unterhält diese Sequenzbybf
ist daher ein UTF-16 big-endian-Darstellung der ZeichenfolgeOlé
So, in diesem code:
Charset utf16 = Charset.forName("UTF-16");
CharBuffer chbf = utf16.decode(bybf);
System.out.println(chbf);
decode()
sollte
- Interpretieren
bybf
als UTF-16 string-Darstellung - "konvertieren", um es in die ursprüngliche Zeichenfolge
Olé
.
Eigentlich kein byte sollte geändert werden, da alles in UTF-16 gespeichert und UTF-16 Charset
sollte eine Art "Neutrale Netzbetreiber". Das Ergebnis ist jedoch so gedruckt, wie:
??
Wie kann das sein?
Zusätzliche Frage: Für die Umwandlung korrekt, es scheint Charset.decode(ByteBuffer bb)
erfordert bb
eine UTF-16 big-endian-byte-Reihenfolge Bild von einem string. Ist das richtig?
Bearbeiten: Von den Antworten, vorausgesetzt, ich habe einige Tests zu drucken ByteBuffer
Inhalt und die chars
die durch Decodierung. Bytes [Codierung mit ="Olé".getBytes(charsetName)
] gedruckt werden, die in Erster Linie von Gruppen, die andere Linie(N) sind die Saiten die durch die Dekodierung zurück bytes [mit Charset#decode(ByteBuffer)
] mit verschiedenen Charset
.
Ich auch bestätigt, dass die Standard-Kodierung für die Speicherung von String in byte[]
auf einem Windows 7-computer ist windows-1252
(es sei denn, strings enthalten chars erfordern UTF-8).
Default VM encoding: windows-1252
Sample string: "Olé"
getBytes() no CS provided : 79 108 233 <-- default (windows-1252), 1 byte per char
Decoded as windows-1252: Olé <-- using the same CS than getBytes()
Decoded as UTF-16: ?? <-- using another CS (doesn't work indeed)
getBytes with windows-1252: 79 108 233 <-- same than getBytes()
Decoded as windows-1252: Olé
getBytes with UTF-8: 79 108 195 169 <-- 'é' in UTF-8 use 2 bytes
Decoded as UTF-8: Olé
getBytes with UTF-16: 254 255 0 79 0 108 0 233 <-- each char uses 2 bytes with UTF-16
Decoded as UTF-16: Olé (254-255 is an encoding tag)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie meistens korrekt.
Den einheitlichen Charakter-Darstellung in java ist UTF-16. Allerdings, wenn die Umwandlung von Zeichen in bytes geben Sie entweder den Zeichensatz, den Sie verwenden, oder das system verwendet die Standardeinstellung, welche meist UTF-8, wenn ich überprüft. Dies ergibt interessante Ergebnisse, wenn Sie mischen und anpassen.
zB für mein system die folgenden
produziert
UTF-8
佬쎩
Olé
So, in diesem Teil ist nur korrekt, wenn die UTF-16 ist das Standard-charset
getBytes() result is this same UTF-16 byte sequence.
Also entweder immer die Angabe des charset-Sie sind mit die am sichersten ist, wie Sie immer wissen, was Los ist, oder immer den Standardwert verwenden.
Ja.
Nicht. Es kodiert für die UTF-16 Zeichen beschränkt, die in der Plattform Standard-Zeichensatz, was auch immer das ist. Veraltet.
wrap()
hält alles.Nicht. Es umschließt die Plattform der Standard-Kodierung der ursprünglichen Zeichenfolge.
Nein, siehe oben.
Nicht, es sei denn, der Plattform-Standard-Kodierung ist "UTF-16".
public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin)
, alle anderen überladenen Versionen dieser Methode (auch die ohne Argumente) sind nicht veraltet.Ich hatte fast das gleiche problem mit Daten codiert in doublebyte-Zeichensatz.
Antwort 3 oben enthält bereits die kritische Fallstricke sollten Sie im Auge behalten.
Folgende code funktioniert
Ersetzen Standard-system-von Ihrem Lieblings-Kodierung.