ByteBuffer, CharBuffer, et le jeu de caractères de la Chaîne
Je suis en train de faire le tri des personnages, de leur représentation dans les séquences d'octets selon les jeux de caractères, et la façon de convertir à partir d'un jeu de caractères à un autre en Java. J'ai quelques difficultés.
Par exemple,
ByteBuffer bybf = ByteBuffer.wrap("Olé".getBytes());
Ma compréhension est que:
- Chaîne sont toujours stockées en tant que UTF-16 séquence d'octets en Java (2 octets par caractère, big endian)
getBytes()
résultat est le même UTF-16 séquence d'octetswrap()
maintient cette séquencebybf
est donc un UTF-16 big endian représentation de la chaîne deOlé
Donc dans ce code:
Charset utf16 = Charset.forName("UTF-16");
CharBuffer chbf = utf16.decode(bybf);
System.out.println(chbf);
decode()
devrait
- Interpréter
bybf
comme UTF-16 représentation de chaîne - "convertir" à la chaîne d'origine
Olé
.
Fait pas d'octet doit être modifié depuis tout est en UTF-16 stockées et UTF-16 Charset
devrait être une sorte de "neutre" d'opérateur. Cependant, le résultat est imprimé en tant que:
??
Comment peut-il être?
Question supplémentaire: Pour convertir correctement, il semble Charset.decode(ByteBuffer bb)
nécessite bb
être un UTF-16 big endian séquence d'octets de l'image d'une chaîne. Est-ce exact?
Modifier: à Partir des réponses fournies, j'ai fait quelques tests pour imprimer un ByteBuffer
contenu et la chars
obtenu par décodage. Octets [encodage ="Olé".getBytes(charsetName)
] sont imprimés sur la première ligne de groupes, l'autre ligne(s) sont les chaînes obtenues par le décodage arrière les octets [avec Charset#decode(ByteBuffer)
] avec divers Charset
.
J'ai aussi confirmé que le codage par défaut pour le stockage de la Chaîne byte[]
sur un ordinateur Windows 7 est windows-1252
(à moins contiennent des chaînes de caractères nécessitant 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)
Vous devez vous connecter pour publier un commentaire.
Vous êtes la plupart du temps correct.
Le natif de représentation des caractères en java est UTF-16. Cependant lors de la conversion de caractères d'octets que vous spécifier le jeu de caractères que vous utilisez, ou le système utilise par défaut c'est ce qui a généralement été UTF-8 chaque fois que j'ai vérifié. Cela donnera des résultats intéressants si vous êtes le mélange et l'appariement.
eg pour mon système, le suivant
produit
UTF-8
佬쎩
Olé
Donc cette partie n'est exacte que si l'UTF-16 est le jeu de caractères par défaut
getBytes() result is this same UTF-16 byte sequence.
Donc soit toujours spécifier le jeu de caractères que vous utilisez qui est la plus sûre que vous saurez toujours ce qui se passe, ou de toujours utiliser la valeur par défaut.
Oui.
Pas. Il code pour l'UTF-16 caractères dans la plate-forme de jeu de caractères par défaut, tout ce qui est. Déconseillé.
wrap()
maintient tout.Pas. Elle enveloppe la plate-forme de l'encodage par défaut de la chaîne d'origine.
Non, voir ci-dessus.
Pas moins que la plate-forme de l'encodage par défaut est "UTF-16".
public void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin)
, toutes les autres versions surchargées de cette méthode (y compris le sans arguments) ne sont pas obsolètes.J'ai eu presque le même problème avec les données codées en double-byte charset.
Réponse 3 ci-dessus contient déjà l'essentiel des pièges que vous devriez garder un oeil sur.
Code suivant fonctionne
Remplacer le système par défaut par votre favori encodage.