Encodage des caractères UTF-8 en Java

j'ai quelques problèmes à obtenir du texte français à convertir en UTF8 pour qu'il puisse être affiché correctement, soit dans une console, un fichier texte ou dans un élément GUI.

la chaîne originale est

HANDICAP NORTHUMB. ES

qui est censé être

HANDICAPÉES

voici un extrait de code qui montre comment j'utilise jackcess pilote de base de données à lire dans le fichier MDB Acccess dans une Eclipse / Linux environnement.

Database database = Database.open(new File(filepath));
Table table = database.getTable(tableName, true);
Iterator rowIter = table.iterator();
while (rowIter.hasNext()) {
    Map<String, Object> row = this.rowIter.next();
    // convert fields to UTF
    Map<String, Object> rowUTF = new HashMap<String, Object>();
    try {
        for (String key : row.keySet()) {
            Object o = row.get(key);
            if (o != null) {
                String valueCP850 = o.toString();
                // String nameUTF8 = new String(valueCP850.getBytes("CP850"), "UTF8"); // does not work!
                String valueISO = new String(valueCP850.getBytes("CP850"), "ISO-8859-1");
                String valueUTF8 = new String(valueISO.getBytes(), "UTF-8"); // works!
                rowUTF.put(key, valueUTF8);
            }
        }
    } catch (UnsupportedEncodingException e) {
        System.err.println("Encoding exception: " + e);
    }   
}

dans le code, vous verrez où je veux convertir directement en UTF8, ce qui ne semble pas fonctionner, donc je dois faire une double conversion. Notez également qu'il ne semble pas y avoir de moyen de spécifier le type d'encodage lorsque vous utilisez le pilote jackcess.

Merci, Cam

10
demandé sur jtahlborn 2010-05-04 19:42:53

4 réponses

Nouvelle analyse, basée sur de nouvelles informations.

Il ressemble à votre problème est avec l'encodage du texte avant il était stocké dans la base de données Access. Il semble qu'il ait été codé comme ISO-8859-1 ou windows-1252, mais décodé comme cp850, résultant en la chaîne HANDICAP╔ES être stocké dans le DB.

ayant correctement récupéré cette chaîne depuis la base de données, vous essayez maintenant d'Inverser l'erreur d'encodage d'origine et de récupérer la chaîne en tant que il doit avoir été stockés: HANDICAPÉES. Et vous êtes l'accomplissement de cette ligne:

String valueISO = new String(valueCP850.getBytes("CP850"), "ISO-8859-1");

getBytes("CP850") convertit le caractère à la valeur de l'octet 0xC9, et le constructeur de chaînes décode que selon ISO-8859 - 1, résultant dans le caractère É. La ligne suivante:

String valueUTF8 = new String(valueISO.getBytes(), "UTF-8");

...ne fait rien. getBytes() code la chaîne dans l'encodage par défaut de la plate-forme, qui est UTF-8 sur votre système Linux. Puis le constructeur de chaînes le décode avec le même codage. Supprimer cette ligne et vous devriez toujours obtenir le même résultat.

plus précisément, votre tentative de créer une "chaîne UTF-8" était malavisée. Vous n'avez pas besoin de vous préoccuper de l'encodage des chaînes de Java--elles sont toujours UTF-16. Lorsque vous apportez du texte dans une application Java, vous avez juste besoin de vous assurer que vous le décodez avec le codage correct.

Et si mon analyse est correcte, votre pilote d'Accès aux décoder correctement, le problème est à l'autre extrémité, peut-être avant même que la base de données n'entre en scène. Qui est ce que vous devez corriger, parce que new String(getBytes()) on ne peut pas compter sur hack pour travailler dans tous les cas.


analyse Originale, basée sur aucun informations.: -/

Si vous voyez les HANDICAP╔ES sur la console, il n'y a probablement pas de problème. Etant donné ce code:

System.out.println("HANDICAPÉES");

la JVM convertit la chaîne (Unicode) en plate-forme codage par défaut, windows-1252, avant de l'envoyer à la console. Puis la console décode qu'en utilisant son encodage par défaut, qui se trouve être cp850. Si la console affiche mal, mais c'est normal. Si vous voulez qu'il s'affiche correctement, vous pouvez modifier l'encodage de la console avec cette commande:

CHCP 1252

pour afficher la chaîne dans un élément GUI, comme un JLabel, vous n'avez pas à faire quoi que ce soit de spécial. Juste assurez-vous que vous utilisez une police qui peut afficher tous les personnages, mais ça ne devrait pas être un problème pour le français.

Comme pour l'écriture d'un fichier, il suffit de spécifier l'encodage souhaité lorsque vous créez de l'Auteur:

OutputStreamWriter osw = new OutputStreamWriter(
    new FileOutputStream("myFile.txt"), "UTF-8");
9
répondu Alan Moore 2010-05-12 00:04:04
String s = "HANDICAP╔ES";
System.out.println(new String(s.getBytes("CP850"), "ISO-8859-1")); // HANDICAPÉES

indique la valeur correcte de la chaîne. Cela signifie que c'était origine codé/décodé avec ISO-8859-1 et tort codé avec CP850 (à l'origine CP1252 A. K. A. Windows ANSI comme indiqué dans un commentaire est en effet également possible depuis le É y a le même codepoint que dans la norme ISO-8859-1).

Alignez votre environnement et les pipelines binaires pour utiliser tous les un et même caractère encodage. Vous ne pouvez pas et ne devriez pas vous convertir entre eux. Vous risquez de perdre des informations dans le non - ASCII portée de cette façon.

Note: n'utilisez pas l'extrait de code ci-dessus pour "corriger" le problème! Ce ne serait pas la bonne solution.


mise à Jour: vous êtes apparemment toujours aux prises avec le problème. Je répète les parties importantes de la réponse:

  1. Alignez votre environnement et votre binaire pipelines à utiliser et codage des caractères.

  2. Vous pouvez et devrait convertir entre eux. Tu risques perdre information dans le non- ASCII portée de cette façon.

  3. utilisez l'extrait de code ci-dessus pour "corriger" le problème! Ce ne serait pas la droit solution.

pour corriger le problème, vous devez choisir le codage de caractères X que vous souhaitez utiliser dans toute l'application. Je suggère UTF-8. Mise à jour de MS Access pour utiliser le codage X. mise à Jour de votre environnement de développement pour utiliser le codage X. mise à Jour de l' java.io lecteurs et rédacteurs de votre code pour utiliser l'encodage X. Mettez à jour votre éditeur pour lire/écrire des fichiers avec l'encodage X. Mettez à jour l'interface utilisateur de l'application pour utiliser l'encodage X. faites utilisez Y ou Z ou que ce soit à une certaine étape. Si les personnages sont déjà corrompu dans certains datastore (accès MS, fichiers, etc), alors vous devez le corriger en remplaçant manuellement les caractères juste là dans le datastore. N'utilisez pas Java pour cela.

si vous utilisez réellement "l'invite de commande" comme interface utilisateur, alors vous êtes réellement perdu. Il ne supporte pas L'UTF-8. Comme suggéré dans les commentaires et dans l'article lié dans les commentaires, vous devez créer un Swing application au lieu de se fier à l'environnement de commande restreint prompt.

8
répondu BalusC 2010-05-12 13:39:10

Vous pouvez spécifier l'encodage lors de l'établissement de la connexion. De cette façon était parfait et à résoudre mon problème d'encodage:

    DatabaseImpl open = DatabaseImpl.open(new File("main.mdb"), true, null, Database.DEFAULT_AUTO_SYNC, java.nio.charset.Charset.availableCharsets().get("windows-1251"), null, null);
    Table table = open.getTable("FolderInfo");
0
répondu Xupypr MV 2014-10-21 08:13:56

en utilisant" ISO-8859-1