155 votes

Java : Comment déterminer le codage correct du jeu de caractères d'un flux ?

En ce qui concerne le fil de discussion suivant : Java App : Impossible de lire correctement un fichier encodé en iso-8859-1

Quelle est la meilleure façon de déterminer par programme l'encodage correct d'un flux d'entrée/fichier ?

J'ai essayé d'utiliser ce qui suit :

File in =  new File(args[0]);
InputStreamReader r = new InputStreamReader(new FileInputStream(in));
System.out.println(r.getEncoding());

Mais sur un fichier dont je sais qu'il est codé avec ISO8859_1, le code ci-dessus donne ASCII, ce qui n'est pas correct, et ne me permet pas de restituer correctement le contenu du fichier à la console.

12 votes

Eduard a raison : "Vous ne pouvez pas déterminer l'encodage d'un flux d'octets arbitraire". Toutes les autres propositions vous donnent des moyens (et des bibliothèques) pour faire la meilleure estimation possible. Mais au final, ce sont toujours des suppositions.

11 votes

Reader.getEncoding renvoie l'encodage que le lecteur a été configuré pour utiliser, qui dans votre cas est l'encodage par défaut.

0 votes

System.getProperty("file.encoding") il renvoie une chaîne de caractères. ex - FileInputStream fis = new FileInputStream(path); String encoding = System.getProperty("fis.encoding");

107voto

Eduard Wirch Points 4102

Vous ne pouvez pas déterminer l'encodage d'un flux d'octets arbitraire. C'est la nature même des encodages. Un encodage signifie une correspondance entre une valeur d'octet et sa représentation. Ainsi, chaque encodage "pourrait" être le bon.

El getEncoding() retournera l'encodage qui a été configuré (lisez la page d'accueil du site web de l'UE). JavaDoc ) pour le flux. Il ne va pas deviner l'encodage pour vous.

Certains flux vous indiquent quel encodage a été utilisé pour les créer : XML, HTML. Mais pas un flux d'octets arbitraire.

Quoi qu'il en soit, vous pouvez essayer de deviner un encodage par vous-même si vous le devez. Chaque langue a une fréquence commune pour chaque caractère. En anglais, le caractère e apparaît très souvent, mais ê n'apparaît que très rarement. Dans un flux ISO-8859-1, il n'y a généralement pas de caractères 0x00. Mais un flux UTF-16 en contient beaucoup.

Ou : vous pourriez demander à l'utilisateur. J'ai déjà vu des applications qui vous présentent un extrait du fichier dans différents codages et vous demandent de sélectionner le "bon".

20 votes

Cela ne répond pas vraiment à la question. L'opérateur devrait probablement utiliser docs.codehaus.org/display/GUESSENC/Home o icu-project.org/apiref/icu4j/com/ibm/icu/text/ o jchardet.sourceforge.net

27 votes

Alors comment mon éditeur, notepad++, peut-il ouvrir le fichier et me montrer les bons caractères ?

12 votes

@Hamidam c'est par chance qu'il vous montre les bons caractères. Lorsqu'il se trompe (et c'est souvent le cas), il existe une option (Menu >> Encodage) qui vous permet de modifier l'encodage.

78voto

Luciano Fiandesio Points 4795

J'ai utilisé cette bibliothèque, similaire à jchardet pour détecter l'encodage en Java : https://github.com/albfernandez/juniversalchardet

7 votes

J'ai trouvé que c'était plus précis : jchardet.sourceforge.net (J'ai fait des tests sur des documents en langues d'Europe occidentale encodés en ISO 8859-1 , Windows-1252, utf-8).

2 votes

Ce juniversalchardet ne fonctionne pas. Il fournit UTF-8 la plupart du temps, même si le fichier est encodé à 100% en Windows-1212.

2 votes

Juniversalchardet est maintenant sur GitHub .

40voto

user345883 Points 163

Regarde ça : http://site.icu-project.org/ (icu4j) ils ont des bibliothèques pour détecter le charset à partir de IOStream Cela pourrait être simple comme ceci :

BufferedInputStream bis = new BufferedInputStream(input);
CharsetDetector cd = new CharsetDetector();
cd.setText(bis);
CharsetMatch cm = cd.detect();

if (cm != null) {
   reader = cm.getReader();
   charset = cm.getName();
}else {
   throw new UnsupportedCharsetException()
}

2 votes

J'ai essayé mais cela échoue grandement : j'ai créé 2 fichiers texte dans eclipse contenant tous deux "öäüß". L'un est réglé sur l'encodage iso et l'autre sur utf8 - les deux sont détectés comme utf8 ! J'ai donc essayé un fichier sauvegardé quelque part sur mon disque dur (Windows) - celui-ci a été détecté correctement ("Windows-1252"). Ensuite, j'ai créé deux nouveaux fichiers sur mon disque dur, un edi

2 votes

14voto

Zach Scrivena Points 15052

Vous pouvez certainement valider le fichier pour un jeu de caractères particulier en décodage avec un CharsetDecoder et faire attention aux erreurs "malformed-input" ou "unmappable-character". Bien sûr, cela ne vous dit que si un jeu de caractères est incorrect ; cela ne vous dit pas s'il est correct. Pour cela, vous avez besoin d'une base de comparaison pour évaluer les résultats décodés, par exemple, savez-vous à l'avance si les caractères sont limités à un certain sous-ensemble, ou si le texte respecte un format strict ? En résumé, la détection des jeux de caractères est une conjecture sans aucune garantie.

4voto

falcon Points 41

J'ai trouvé une belle bibliothèque tierce qui peut détecter l'encodage réel : http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding

Je ne l'ai pas testé de manière approfondie mais cela semble fonctionner.

1 votes

Le lien vers le site web du projet "GuessEncoding" est le suivant : xircles.codehaus.org/p/guessencoding

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X