web-dev-qa-db-fra.com

Java Problème d’encodage FileReader

J'ai essayé d'utiliser Java.io.FileReader pour lire des fichiers texte et les convertir en chaîne, mais j'ai trouvé que le résultat était mal codé et illisible.

Voici mon environnement:

  • Windows 2003, codage du système d'exploitation: CP1252

  • Java 5.0

Mes fichiers sont codés UTF-8 ou CP1252, et certains d’entre eux (fichiers UTF-8) peuvent contenir des caractères chinois (non latins).

J'utilise le code suivant pour faire mon travail:

   private static String readFileAsString(String filePath)
    throws Java.io.IOException{
        StringBuffer fileData = new StringBuffer(1000);
        FileReader reader = new FileReader(filePath);
        //System.out.println(reader.getEncoding());
        BufferedReader reader = new BufferedReader(reader);
        char[] buf = new char[1024];
        int numRead=0;
        while((numRead=reader.read(buf)) != -1){
            String readData = String.valueOf(buf, 0, numRead);
            fileData.append(readData);
            buf = new char[1024];
        }
        reader.close();
        return fileData.toString();
    }

Le code ci-dessus ne fonctionne pas. J'ai trouvé que le codage FileReader est CP1252 même si le texte est codé en UTF-8. Mais le JavaDoc de Java.io.FileReader dit que:

Les constructeurs de cette classe supposent que le codage de caractères par défaut et la taille de tampon d'octets par défaut sont appropriés.

Est-ce que cela signifie que je ne suis pas obligé de définir l'encodage des caractères moi-même si j'utilise FileReader? Mais je me suis actuellement trompé de données encodées. Quelle est la bonne façon de gérer ma situation? Merci.

124
nybon

Oui, vous devez spécifier le codage du fichier que vous souhaitez lire.

Oui, cela signifie que vous devez connaître le codage du fichier que vous souhaitez lire.

Non, il n'y a pas de moyen général pour deviner l'encodage d'un fichier "texte brut" donné.

Les constructeurs de FileReader utilisent toujours le codage par défaut de la plate-forme qui est généralement une mauvaise idée .

Au lieu de FileReader, vous devez utiliser new InputStreamReader(new FileInputStream(pathToFile), <encoding>).

233
Joachim Sauer

FileReader utilise le codage par défaut de la plate-forme Java, qui dépend des paramètres système de l'ordinateur sur lequel il est exécuté. Il s'agit généralement du codage le plus répandu parmi les utilisateurs de ces paramètres régionaux.

Si cette "meilleure estimation" n'est pas correcte, vous devez spécifier explicitement le codage. Malheureusement, FileReader ne le permet pas (supervision majeure dans l'API). Au lieu de cela, vous devez utiliser new InputStreamReader(new FileInputStream(filePath), encoding) et idéalement obtenir l'encodage à partir de métadonnées sur le fichier.

77
Michael Borgwardt

Depuis Java 11, vous pouvez utiliser ceci:

public FileReader(String fileName, Charset charset) throws IOException;
5
Radoslav Ivanov

Pour Java 7+ doc vous pouvez utiliser ceci:

BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);

Voici tous les jeux de caractères doc

Par exemple, si votre fichier est dans CP1252, utilisez ceci méthode

Charset.forName("windows-1252");

Voici d'autres noms canoniques pour Java encodages à la fois pour IO et NIO doc

Si vous ne connaissez pas exactement l'encodage que vous avez dans un fichier, vous pouvez utiliser des bibliothèques tierces comme cet outil de Google this qui fonctionne assez bien.

1
Andreas Gelever