Question

J'ai un problème avec des caractères spéciaux turcs sur des machines différentes. Le code suivant:

String turkish = "ğüşçĞÜŞÇı";

String test1 = new String(turkish.getBytes());
String test2 = new String(turkish.getBytes("UTF-8"));
String test3 = new String(turkish.getBytes("UTF-8"), "UTF-8");

System.out.println(test1);
System.out.println(test2);
System.out.println(test3);

Sur un Mac les trois chaînes sont les mêmes que la chaîne d'origine. Sur une machine Windows, les trois lignes sont (imprimées avec la console Netbeans 6.7):

?ü?ç?Ü?Ç?
ğüşçĞÜŞÇı
?ü?ç?Ü?Ç?

Je ne comprends pas le problème.

Était-ce utile?

La solution

String test1 = new String(turkish.getBytes());

Vous prenez la chaîne Unicode, y compris les caractères turcs, et le transformer en octets en utilisant l'encodage par défaut (en utilisant l'encodage par défaut est généralement une erreur). Vous êtes alors prendre les octets et les décoder en chaîne de caractères, en utilisant à nouveau l'encodage par défaut. Le résultat est que vous avez rien fait (à l'exception de perdre des caractères qui ne correspondent pas à l'encodage par défaut); si vous avez mis une chaîne par un cycle de codage / décodage a aucun effet sur ce que le fait System.out.println(test1) suivant l'impression parce que c'est encore une chaîne et non octets.

String test2 = new String(turkish.getBytes("UTF-8"));

Encode en UTF-8 et décode en utilisant l'encodage par défaut. Sur Mac l'encodage par défaut est UTF-8 donc cela ne fait rien. Sous Windows, le codage par défaut est jamais UTF-8 de sorte que le résultat est les mauvais caractères.

String test3 = new String(turkish.getBytes("UTF-8"), "UTF-8");

ne précise rien.

Pour écrire les chaînes à stdout avec un codage différent de l'encodage par défaut, vous allez pouvoir créer quelque chose comme encodeur new OutputStreamWriter(System.out, "cp1252") et envoyer le contenu de la chaîne à cela.

Cependant, dans ce cas, il semble que la console utilise la page de code Windows 1252 Europe occidentale (+1 ATorres). Il n'y a pas de problème de décalage d'encodage du tout ici, donc vous ne serez pas en mesure de le résoudre par des chaînes réencodage!

Le codage par défaut CP1252 correspond à l'encodage de la console, il est juste que CP1252 ne contient pas les caractères turcs ğşĞŞı du tout. Vous pouvez voir les autres caractères que sont CP1252, üçÜÇ, passer par bien. À moins que vous pouvez reconfigurer la console pour utiliser un autre encodage qui ne comprend tous les caractères que vous voulez, il n'y a aucun moyen que vous serez en mesure de sortie de ces caractères.

On peut supposer que sur un ordinateur Windows turc installation, la page de code par défaut sera cp1254 à la place et vous obtiendrez les caractères que vous attendez (mais d'autres personnages ne fonctionnent pas). Vous pouvez le tester en changeant la «langue à utiliser pour les applications non-Unicode de réglage dans l'application Panneau de configuration Options régionales et linguistiques.

Malheureusement, aucune localisation Windows utilise UTF-8 comme la page de code par défaut. Mettre la sortie non-ASCII sur la console avec les fonctions de flux stdio est pas quelque chose qui est vraiment fiable du tout. Il y a une API Win32 pour écrire Unicode directement à la console, mais malheureusement pas grand-chose utilise.

Autres conseils

Ne comptez pas sur la console ou sur le codage de la plate-forme par défaut. Toujours spécifier le codage de caractères pour les appels comme getBytes et le constructeur de chaîne prenant un tableau d'octets, et si vous voulez examiner le contenu d'une chaîne, imprimez la valeur unicode de chaque caractère.

Je conseillerais aussi soit restreindre votre code source à utiliser ASCII (et \ uxxxx pour encoder des caractères non-ASCII) ou spécifiant explicitement le codage de caractères lorsque vous compilez.

Maintenant, ce problème plus grave que vous essayez de résoudre?

Vous pouvez avoir affaire avec des paramètres différents de l'encodage par défaut.

java -Dfile.encoding=utf-8

contre

java -Dfile.encoding=something else

Ou, vous pouvez juste être voir le fait que la fenêtre du terminal Mac fonctionne en UTF-8, et la boîte DOS Windows ne pas travail en UTF-8.

Selon M. Skeet, vous avez un troisième problème possible, ce qui est que vous essayez d'intégrer UTF-8 caractères dans votre source. Selon les options du compilateur, vous pouvez ou ne pouvez pas obtenir ce que vous avez l'intention là. Mettez ces données dans un fichier de propriétés, ou utilisez \ u échappe.

Enfin, également par M. Skeet, jamais, jamais appeler les getBytes sans argument ().

Si vous utilisez le compilateur AspectJ ne pas oublier de le définir est l'encodage en UTF-8 aussi. J'ai eu du mal à trouver pendant des heures.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top