Maison >Problème commun >Quelle est la cause des caractères chinois tronqués ?
La raison des caractères chinois tronqués : la méthode de décodage et la méthode d'encodage sont incohérentes. Un caractère chinois codé en UTF-8 sera converti en 3 octets, et s'il est codé en gbk, il sera converti en 2 octets ; et un caractère anglais codé en UTF-8 sera converti en 1 octet, s'il est codé en gbk, il le sera. être converti en 1 octet.
L'environnement d'exploitation de ce tutoriel : système Windows 7, ordinateur Dell G3.
Je ne sais pas si quelqu'un y a déjà pensé de cette façon. Une chaîne contient non seulement des caractères, mais également des informations d'encodage qui la cachent. Par exemple, String str = "Bonjour" en Java ; je pensais cela auparavant, la chaîne str cache sa méthode d'encodage unicode ou gbk, iso-8859-1, etc. Cette compréhension est erronée. Les caractères ne sont que des caractères sans aucune autre information. La bonne compréhension devrait être que la chaîne que les gens voient dans un fichier est le système qui lit les informations numériques dans la mémoire et les décode ensuite. Les caractères sont affichés en dernier. , c'est-à-dire que lorsque vous double-cliquez pour ouvrir un fichier texte, le système lira et affichera les informations numériques dans la mémoire. Lorsque vous enregistrez un fichier texte, le système encodera le fichier selon la méthode d'encodage que vous avez définie, puis le mettra. dans la mémoire. Donc les caractères tronqués sont aussi des caractères, juste des caractères étranges, et il n'y a pas de "code".
Parlons ensuite des raisons des codes tronquésLa question que nous voulons poser est donc la suivante : pourquoi des codes tronqués apparaissent-ils lorsque la méthode de décodage et la méthode d'encodage sont incohérentes.
Voici les trois méthodes d'encodage utf-8, gbk et iso-8859-1 à titre d'exemples.
@Test public void testEncode() throws Exception { String str = "你好",en = "h?h"; System.out.println("========中文字符utf-8======="); byte[] utf8 = str.getBytes(); // 以utf-8方式编码 ,default:utf-8 for (byte b : utf8) { System.out.print(b + "\t"); } System.out.println("\n"+"========英文字符utf-8======="); byte[] utf8_en = en.getBytes(); // 以utf-8方式编码 ,default:utf-8 for (byte b : utf8_en) { System.out.print(b + "\t"); } System.out.println("\n"+"========中文字符gbk========="); byte[] gbk = str.getBytes("gbk"); for (byte b : gbk) { System.out.print(b + "\t"); } System.out.println("\n"+"========英文字符gbk========="); byte[] gbk_en = en.getBytes("gbk"); for (byte b : gbk_en) { System.out.print(b + "\t"); } String s = new String(utf8,"utf-8"); String s1 = new String(utf8,"gbk"); System.out.println("\n"+s + "====gbk:" + s1); }
Testez la méthode ci-dessus, et le résultat imprimé est :
========中文字符utf-8======= -28 -67 -96 -27 -91 -67 ========英文字符utf-8======= 104 63 104 ========中文字符gbk========= -60 -29 -70 -61 ========英文字符gbk========= 104 63 104 你好====gbk:浣犲ソ ------------------------------------------------------------------------------------
On peut conclure que :
Un caractère chinois sera converti en 3 octets s'il est codé avec utf-8, et s'il est codé avec gbk, il sera converti en 2 octets ;
Un caractère anglais sera converti en 1 octet s'il est codé en utf-8, et s'il est codé en gbk, il sera converti en 1 octet.
Il ressort de la dernière ligne d'impression combinée aux lignes 29 à 31 du code que si le tableau d'octets utf8 est décodé en mode utf-8, il n'y aura pas de caractères tronqués, et ce sera toujours le cas. le "Bonjour" original, et s'il est décodé en mode gbk Lors du décodage, trois caractères tronqués sont apparus. Pourquoi y a-t-il 3 au lieu de 2 ?
Parlons ensuite de l'iso-8859-1. Cet encodage est utilisé dans la série anglaise, ce qui signifie qu'il ne peut pas représenter le chinois (si vous souhaitez l'utiliser, vous devez vous fier à d'autres encodages compatibles avec l'iso-8859. -1 méthode d'encodage). Il ne peut pas être lu. Les caractères seront traités comme des points d'interrogation anglais '?'. Le nombre d'encodage iso-8859-1 des points d'interrogation anglais est : 63 (décimal) (en fait, dans presque toutes les méthodes d'encodage). , tous les caractères anglais utilisent une représentation de code d'octet fixe, à l'exception du codage Unicode).
@Test public void testISO() throws Exception { String str = "你好"; byte[] bs = str.getBytes("iso-8859-1"); for (byte b : bs) { System.out.println(b); } System.out.println(new String(bs,"iso-8859-1")); System.out.println(new String(bs,"utf-8")); System.out.println(new String(bs,"gbk")); System.out.println(new String(bs,"unicode")); }
Imprimer les résultats
63 63 ?? ?? ?? 㼿
Explication 63 =》?, tous les chinois sont considérés ?, donc quand ce code est exécuté : byte[] bs = "Hello".getBytes("iso-8859-1" );Les informations ont été perdu.
Execute String str = new String(bs, "any charset"); str n'est plus égal à "Bonjour", mais deux points d'interrogation ??. Ainsi, dans Tomcat, nous rencontrons souvent des caractères chinois se transformant en une longue chaîne de ??????, ce qui en est l'origine.
En iso-8859-1, utf-8 et gbk, un bytecode représente un caractère anglais
En codage Unicode, un bytecode ne peut représenter aucun caractère, et il est stipulé qu'il doit s'agir de deux bytecodes (parfois 4) peut représenter un personnage.
Cela dit, beaucoup de gens peuvent se demander pourquoi tant de méthodes d'encodage sont utilisées. Tous les caractères peuvent-ils être représentés en les unifiant en utf-8 ?
Le codage ne consiste pas seulement à savoir s'il peut représenter des caractères, mais également à transmettre et à stocker.
1. UTF-8 peut en effet représenter presque tous les caractères connus. Comme mentionné précédemment, seuls 3 octets représentent un caractère chinois en codage UTF-8, ce qui prend évidemment de la place et n'est pas propice à la transmission et au stockage (la transmission et le stockage se font tous deux en binaire)Comprendre les règles des différentes méthodes d'encodage : https://jingyan.baidu.com/article/020278118741e91bcd9ce566.html2. Le caractère économise le plus d'espace, comme iso-8859-1. Mais il n’y a pas seulement des personnages anglais dans le monde, mais aussi des personnages de diverses régions et pays. Le nombre de caractères doit donc être supérieur à 2 à la puissance 8.
Ainsi en combinant les deux points ci-dessus, de nombreuses méthodes d'encodage apparaissent naturellement.
Pour plus de connaissances liées à la programmation, veuillez visiter : Enseignement de la programmation ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!