2013-10-11 4 views
5

J'ai lu des données de flux en encodage UTF-8Java substring encodage cassé

String line = new String(byteArray, "UTF-8"); 

puis essayer de trouver une séquence

int startPos = line.indexOf(tag) + tag.length(); 
int endPos = line.indexOf("/", startPos); 

et la couper

String name = line.substring(startPos, endPos); 

Dans la plupart cas ça fonctionne bien, mais parfois le résultat est cassé. Par exemple, pour le nom d'entrée comme "гордунни" j'ai obtenu des valeurs comme "горд��нни", "горду��ни", "г��рдунни" etc. Il semble que les paires de substitution sont rompues de manière aléatoire pour une raison quelconque. Je l'ai eu 4 fois sur 1000.

Comment le réparer? Ai-je besoin d'utiliser d'autres méthodes String au lieu de indexOf() + substring() ou d'utiliser une magie d'encodage/décodage sur mon résultat?

+1

Est-ce problème sur Linux? Où regardez-vous des lignes «cassées»? J'ai eu le même problème dans la table SWT, mais quand j'envoie cette chaîne dans SWT Text ou Label, elle s'affiche correctement. Le plus probable est un problème d'affichage. – Nicolai

+0

Il est vrai que les méthodes 'indexOf' et' substring' fonctionnent sur des points de code, donc potentiellement ils peuvent casser des paires de substitution, mais 'гордунни' n'a pas de paire de substitution! Etes-vous sûr que le texte a été correctement lu pour commencer? – Joni

+0

Est-ce que cela produit le même résultat si vous ajoutez -Dfile.encoding = UTF-8 à la ligne de commande? – Alcanzar

Répondre

0

Afin de sortir ceci de la file d'attente 'non répondue'.

Le problème se produit car le flux a été lu sous la forme de blocs d'octets, parfois en séparant des caractères UTF-8 multi-octets. En enveloppant l'InputStream dans un InputStreamReader, vous lirez des blocs de caractères (par opposition à des blocs d'octets), et les caractères UTF-8 multi-octets survivront.

-1

Si je me souviens, cela peut être un problème matériel qui est très commun. Mon instructeur de programmation au collège nous a expliqué qu'au niveau binaire, avec 32bit 64bit etc. tout type de PC, les charges ont tendance à sauter d'une ligne à l'autre lors du calcul, cela peut entraîner des résultats erronés, par exemple pour les doubles en Java , beaucoup de mes amis obtiendraient 1.9999999999993435 au lieu de 2.0 choses comme ça.

Avez-vous essayé d'exécuter votre code sur un autre ordinateur pour vous assurer que ce n'est pas ce problème? je pourrais être confondu avec completly, je ne suis pas la personne la plus knowledgable en ce qui concerne des questions comme celles-ci

+0

Ceci concerne la représentation en mémoire des valeurs à virgule flottante et n'a rien à voir avec la question. –

0

Dans votre exemple, pouvez-vous montrer le contenu de byteArray, de la ligne et de l'étiquette? Pouvez-vous également montrer quelle longueur sera obtenue, quel startPos et quel endPos? Je veux dire, dans la chaîne "гордунни" il n'y a pas de "/"! Et pourquoi calculez-vous l'endPos? Quelle est la chaîne à l'intérieur de l'étiquette? Êtes-vous sûr que le second paramètre de substring est le endpos et non la longueur? Il est vrai que "гордунни" n'a pas besoin de paires de substitution car tous les codes sont en dessous de 0xFFFF, mais une fois dans votre chaîne utf-16 il y a au moins une paire de substitution, je parie que la longueur de la chaîne éléments et non le nombre de points de code. Je ne suis pas sûr de Java, mais en C#, la longueur vous donne le nombre d'éléments. Pour obtenir le nombre de caractères/points de code, vous devrez utiliser la classe StringInfo en C#. Vérifiez également si vous avez une nomenclature dans votre chaîne. Qu'est-ce que


String line = new String (byteArray, "UTF-8");

faire? Le tableau d'octets est-il une chaîne encodée en utf-8 transformée en utf-16? Contient-il une nomenclature utf-8? La chaîne a-t-elle ensuite une nomenclature utf-16LE ou utf-16BE?

+0

Envoyé les questions sur les nomenclatures, la chaîne sera codée comme une chaîne UTF-16 qui aura une nomenclature uniquement si la chaîne UTF-8 a une nomenclature (qui, selon la spécification qu'elle devrait avoir) –