En référence au thread suivant: Application Java: impossible de lire correctement le fichier encodé iso-8859-1
Quelle est la meilleure façon de déterminer par programme le codage de jeu de caractères 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 encodé avec ISO8859_1, le code ci-dessus renvoie ASCII, ce qui n'est pas correct, et ne me permet pas de restituer correctement le contenu du fichier sur la console.
Reader.getEncoding
renvoie le codage que le lecteur a été configuré pour utiliser, qui dans votre cas est le codage par défaut.Réponses:
J'ai utilisé cette bibliothèque, similaire à jchardet pour détecter l'encodage en Java: http://code.google.com/p/juniversalchardet/
la source
Vous ne pouvez pas déterminer le codage d'un flux d'octets arbitraire. C'est la nature des encodages. Un codage signifie un mappage entre une valeur d'octet et sa représentation. Ainsi, chaque encodage «pourrait» être le bon.
La méthode getEncoding () retournera l'encodage qui a été mis en place (lisez le JavaDoc ) pour le flux. Il ne devinera pas 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 nécessaire. Chaque langue a une fréquence commune pour chaque caractère. En anglais, le caractère apparaît très souvent mais ê apparaîtra très 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 a beaucoup.
Ou: vous pouvez demander à l'utilisateur. J'ai déjà vu des applications qui vous présentent un extrait du fichier dans différents encodages et vous demandent de sélectionner le "correct".
la source
Vérifiez ceci: http://site.icu-project.org/ (icu4j) ils ont des bibliothèques pour détecter le jeu de caractères d'IOStream pourrait être simple comme ceci:
la source
Voici mes favoris:
TikaEncodingDetector
Dépendance:
Échantillon:
GuessEncoding
Dépendance:
Échantillon:
la source
CharsetDectector
.Vous pouvez certainement valider le fichier pour un jeu de caractères particulier en le décodant avec un
CharsetDecoder
et en faisant attention aux erreurs "malformed-input" ou "unmappable-character". Bien sûr, cela ne vous indique que si un jeu de caractères est incorrect; il ne vous dit pas si c'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 sous-ensemble ou si le texte adhère à un format strict? L'essentiel est que la détection des jeux de caractères est une supposition sans aucune garantie.la source
Quelle bibliothèque utiliser?
Au moment d'écrire ces lignes, ce sont trois bibliothèques qui émergent:
Je n'inclus pas Apache Any23 car il utilise ICU4j 3.4 sous le capot.
Comment savoir lequel a détecté le bon jeu de caractères (ou le plus proche possible)?
Il est impossible de certifier le jeu de caractères détecté par chacune des bibliothèques ci-dessus. Cependant, il est possible de leur demander à tour de rôle et de noter la réponse renvoyée.
Comment noter la réponse retournée?
Chaque réponse peut se voir attribuer un point. Plus une réponse a de points, plus le jeu de caractères détecté est fiable. Il s'agit d'une méthode de notation simple. Vous pouvez en élaborer d'autres.
Existe-t-il un exemple de code?
Voici un extrait complet de la mise en œuvre de la stratégie décrite dans les lignes précédentes.
Améliorations: la
guessEncoding
méthode lit entièrement le flux d'entrée. Pour les grands flux d'entrée, cela peut être un problème. Toutes ces bibliothèques liraient tout le flux d'entrée. Cela impliquerait une grande consommation de temps pour détecter le jeu de caractères.Il est possible de limiter le chargement initial des données à quelques octets et d'effectuer la détection du jeu de caractères sur ces quelques octets uniquement.
la source
Les bibliothèques ci-dessus sont de simples détecteurs de nomenclature qui, bien sûr, ne fonctionnent que s'il y a une nomenclature au début du fichier. Jetez un œil à http://jchardet.sourceforge.net/ qui scanne le texte
la source
Autant que je sache, il n'existe pas de bibliothèque générale dans ce contexte pour convenir à tous les types de problèmes. Donc, pour chaque problème, vous devez tester les bibliothèques existantes et sélectionner la meilleure qui satisfait les contraintes de votre problème, mais souvent aucune d'elles n'est appropriée. Dans ces cas, vous pouvez écrire votre propre détecteur d'encodage! Comme je l'ai écrit ...
J'ai écrit un outil meta java pour détecter le codage de charset des pages Web HTML, en utilisant IBM ICU4j et Mozilla JCharDet comme composants intégrés. Ici vous pouvez trouver mon outil, veuillez lire la section README avant toute autre chose. En outre, vous pouvez trouver quelques concepts de base de ce problème dans mon article et dans ses références.
Ci-dessous, j'ai fourni quelques commentaires utiles que j'ai expérimentés dans mon travail:
la source
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.
la source
Si vous utilisez ICU4J ( http://icu-project.org/apiref/icu4j/ )
Voici mon code:
N'oubliez pas de mettre tout le try-catch qu'il faut.
J'espère que cela fonctionne pour vous.
la source
Si vous ne connaissez pas l'encodage de vos données, ce n'est pas si facile à déterminer, mais vous pouvez essayer d'utiliser une bibliothèque pour le deviner . Il y a aussi une question similaire .
la source
Pour les fichiers ISO8859_1, il n'existe pas de moyen facile de les distinguer de l'ASCII. Pour les fichiers Unicode, cependant, on peut généralement le détecter sur la base des premiers octets du fichier.
Les fichiers UTF-8 et UTF-16 incluent une marque d'ordre d'octet (BOM) au tout début du fichier. La nomenclature est un espace insécable de largeur nulle.
Malheureusement, pour des raisons historiques, Java ne le détecte pas automatiquement. Des programmes comme Notepad vérifieront la nomenclature et utiliseront le codage approprié. En utilisant unix ou Cygwin, vous pouvez vérifier la nomenclature avec la commande file. Par exemple:
Pour Java, je vous suggère de consulter ce code, qui détectera les formats de fichiers courants et sélectionnera le bon encodage: Comment lire un fichier et spécifier automatiquement le bon encodage
la source
Une alternative à TikaEncodingDetector est d'utiliser Tika AutoDetectReader .
la source
En Java clair:
Cette approche essaiera les encodages un par un jusqu'à ce que l'un d'eux fonctionne ou que nous en manquions. (BTW ma liste d'encodages ne contient que ces éléments car ce sont les implémentations de jeux de caractères requises sur chaque plate-forme Java, https://docs.oracle.com/javase/9/docs/api/java/nio/charset/Charset.html )
la source
Pouvez-vous choisir le jeu de caractères approprié dans le constructeur :
la source