J'ai un test simple,
@Test
public void utf16SizeTest() throws Exception {
final String test = "п";
// 'п' = U+043F according to unicode table
// 43F to binary = 0100 0011 1111 (length is 11)
// ADD '0' so length should be = 16
// 0000 0100 0011 1111
// 00000100(2) 00111111(2)
// 4(10) 63(10)
final byte[] bytes = test.getBytes("UTF-16");
for (byte aByte : bytes) {
System.out.println(aByte);
}
}
Comme vous pouvez le voir , je tout d' abord convertir « п » en binaire, puis ajouter autant de piqûres vides tandis que length != 16
.
A attendre à ce que la sortie sera 4 , 63
Mais une réelle était:
-2
-1
4
63
Qu'est-ce que je fais mal?
Si tu essayes:
final String test = "ппп";
vous trouverez -2 -1
apparaît seulement au début:
-2
-1
4
63
4
63
4
63
-2 est 0xFE
et est -1 0xFF
. Ensemble, ils forment un BOM (Byte_order_mark)
:
En UTF-16, une nomenclature (U + FEFF) peut être placé comme le premier caractère d'un fichier ou d'un flux de caractère pour indiquer le endianness (ordre des octets) de toutes les unités de code les 16 bits du fichier ou flux. Si une tentative est faite de lire ce flux avec le mauvais boutisme, les octets seront permutés, délivrant ainsi le caractère U + FFFE, qui est défini par Unicode comme un « caractère non » qui ne devrait jamais apparaître dans le texte.
test.getBytes("UTF-16");
par défaut à utiliser Big Endian lors de l'encodage des octets, donc une nomenclature est inclus devant donc les processeurs plus peuvent savoir que Big Endian a été utilisé.
Vous pouvez spécifier explicitement endian à l'aide UTF-16LE
ouUTF-16BE
à la place, évitant ainsi une nomenclature dans la sortie:
final byte[] bytes = test.getBytes("UTF-16BE");
Les
UTF-16
jeux de caractères utilisent des quantités seize bits et sont donc sensibles à l' ordre des octets. Dans ces codages l'ordre des octets d'un courant peut être indiquée par une première marque d'ordre d' octet représenté par le caractère Unicode'\uFEFF'
. Marques octet d'ordre sont traitées comme suit:
Lors du décodage, le
UTF-16BE
et lesUTF-16LE
jeux de caractères interpréter les marques d'ordre des octets initiaux en tant queZERO-WIDTH NON-BREAKING SPACE
; lors de l' encodage, ils n'écrivent pas des marques d'ordre d'octet .Lors du décodage, les
UTF-16
charset interprète la marque d'ordre d' octet au début du flux d'entrée pour indiquer l'ordre des octets du flux , mais par défaut big-endian s'il n'y a pas de marque d'ordre d'octet; lors de l' encodage, il utilise l' ordre des octets big-endian et écrit un grand-boutiste marque d'ordre des octets .