Application Java : Impossible de lire les iso-8859-1 fichier encodé correctement
J'ai un fichier qui est encodé en iso-8859-1, et contient des caractères tels que ô .
Je suis à la lecture de ce fichier avec le code java, quelque chose comme:
File in = new File("myfile.csv");
InputStream fr = new FileInputStream(in);
byte[] buffer = new byte[4096];
while (true) {
int byteCount = fr.read(buffer, 0, buffer.length);
if (byteCount <= 0) {
break;
}
String s = new String(buffer, 0, byteCount,"ISO-8859-1");
System.out.println(s);
}
Cependant le " caractère est toujours brouillé, généralement l'impression d'être un ? .
J'ai lu sur le sujet (et appris un peu sur le chemin), par exemple
- http://www.joelonsoftware.com/articles/Unicode.html
- http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
- http://www.ingrid.org/java/i18n/utf-16/
mais ne peut toujours pas obtenir ce travail
Il est intéressant de noter cela fonctionne sur mon pc (xp), mais pas sur mon linux.
J'ai vérifié que mon jdk prend en charge le nécessaire charsets (ils sont de série, de sorte que ce n'est pas une surprise) à l'aide de :
System.out.println(java.nio.charset.Charset.availableCharsets());
- Je dois ajouter que je suis capable de voir les personnages ou le fichier d'origine correctement à l'aide de mon terminal linux, si je chat le contenu du fichier
- Ce codage de caractères utilisé par votre terminal?
- Il est intéressant de noter - si j'ajoute le runtime java de propriété "-Dfile.encoding=UTF16" il fonctionne comme prévu, même si je ne vois pas pourquoi cela devrait avoir de l'importance - et je ne vois pas cela comme une solution, mais plus d'un hack. Il ne fonctionne pas avec la propriété définie à l'UTF8.
Vous devez vous connecter pour publier un commentaire.
Je soupçonne que votre fichier n'est pas fait encodé en ISO-8859-1, ou d'un Système.ça ne veut pas savoir comment imprimer le caractère.
Je recommande de vérifier pour la première, vous examinent les octets dans le fichier. De vérifier pour la deuxième, examiner le caractère pertinent de la chaîne, de l'impression avec
Dans les deux cas, le résultat devrait être 244 décimal; 0xf4 hex.
Voir mon article sur Unicode débogage pour les conseils généraux (le code est en C#, mais il est facile de se convertir à Java, et les principes sont les mêmes).
En général, par le chemin, j'avais envelopper le flux avec un
InputStreamReader
avec le bon encodage, il est plus facile que de créer de nouvelles chaînes "à la main". Je réalise que ce n'est peut-être le code de démonstration si.EDIT: Voici un moyen facile de prouver si oui ou non la console de travail:
De l'analyse du fichier en tant que blocs de taille fixe d'octets n'est pas bon --- ce si certain personnage a un octet de la représentation qui se situe à cheval entre deux blocs? Utiliser un
InputStreamReader
avec l'encodage de caractères approprié à la place:Btw, n'oubliez pas de vérifier que les caractères unicode peuvent en effet être affichés correctement. Vous pouvez également rediriger la sortie du programme vers un fichier et de le comparer avec le fichier d'origine.
Comme Jon Skeet suggère, le problème peut également être la console liés. Essayez
System.console().printf(s)
pour voir si il y a une différence.@Joel - votre propre réponse confirme que le problème est la différence entre le codage par défaut sur votre système d'exploitation (UTF-8, l'un Java a ramassé) et à l'encodage de votre terminal à l'aide de l'ISO (ISO-8859-1).
Considérer ce code:
Par défaut, mon Ubuntu (8.04) terminal utilise le codage UTF-8. Avec ce codage, c'est imprimée:
Si je passe du terminal de l'encodage ISO 8859-1, c'est imprimée:
Dans les deux cas, la même octets sont émis par le programme Java:
La seule différence est dans la façon dont le terminal est interpréter les octets qu'il reçoit. Jeu de caractères ISO 8859-1, ô est codé comme 0xF4. En UTF-8, ô est codé comme 0xC3B4. Les autres personnages sont communs aux deux codages.
5554 462d 380a f4c3 b40a
dump ? Certainement pas leSystem.out.write(data)
appel ?System.out
. Le0A
octets marque les retours à la ligne écrite parprintln
. Il y avait une réponse écrite par l'auteur de la question, depuis supprimé, mais je ne pense pas être capable de lire, il ajoute beaucoup.Si vous le pouvez, essayez d'exécuter votre programme à debugger pour voir ce qui est à l'intérieur de votre " s " de la chaîne de fois qu'il est créé. Il est possible qu'il ait corriger le contenu, mais la sortie est tronqué après le Système.out.println(s) d'appel. Dans ce cas, il est probablement décalage entre ce que Java pense est l'encodage de votre sortie et l'encodage de caractères de votre terminal/console sous Linux.
En gros, si il fonctionne sur votre PC XP mais pas sous Linux, et vous êtes l'analyse de l'exacte même fichier (c'est à dire vous l'avez transféré de façon binaire entre les cases), puis il a probablement quelque chose à voir avec le Système.out.println appel. Je ne sais pas comment vous vérifiez la sortie, mais si vous le faites en vous connectant avec un shell à distance à partir de la boîte de XP, ensuite, il ya le jeu de caractères de la coquille (et le client) à prendre en compte.
En outre, ce que Zach Scrivena l'indique est vrai aussi - vous ne pouvez pas supposer que vous pouvez créer des chaînes à partir de blocs de données de cette façon - soit utiliser un InputStreamReader ou de lire l'intégralité des données dans un tableau en premier (évidemment pas d'aller travailler pour un gros fichier). Cependant, puisqu'il ne semble pas fonctionner sur XP, alors je crois que ce n'est probablement pas votre problème dans ce cas précis.