CodeGym /Cours /JAVA 25 SELF /Définir l’encodage lors de la lecture/écriture de fichier...

Définir l’encodage lors de la lecture/écriture de fichiers

JAVA 25 SELF
Niveau 37 , Leçon 2
Disponible

1. Introduction

Soyons francs : si vous avez déjà vu à la place d’un texte russe quelque chose comme Привет, vous êtes déjà victime d’un mauvais encodage. Cela arrive lorsque le fichier a été écrit avec un encodage et lu avec un autre. Par exemple, le fichier a été enregistré en UTF-8 et lu comme Windows-1251, ou inversement.

Par défaut, Java utilise l’encodage système, que vous pouvez obtenir ainsi :

System.out.println(System.getProperty("file.encoding"));

Sur un ordinateur, cela peut être UTF-8, sur un autre — Windows-1251, et ailleurs — ISO-8859-1. C’est pourquoi il vaut toujours mieux préciser l’encodage explicitement. C’est particulièrement important si vous travaillez avec des données multilingues, si les fichiers seront utilisés sur différents ordinateurs ou ouverts dans d’autres programmes, ou si vous voulez que votre code se comporte de la même manière dans n’importe quel environnement, et pas seulement sur votre machine.

La classe Charset : votre alliée dans le monde des encodages

En Java, la gestion des encodages se fait via la classe java.nio.charset.Charset. Elle permet de spécifier l’encodage par son nom (par exemple, "UTF-8") ou d’utiliser des constantes standard (StandardCharsets.UTF_8).

Exemples d’encodages standard :

Encodage Constante Java
UTF-8
StandardCharsets.UTF_8
UTF-16
StandardCharsets.UTF_16
ISO-8859-1
StandardCharsets.ISO_8859_1
Windows-1251
Charset.forName("Windows-1251")

Il est préférable d’utiliser les constantes : moins de risques de se tromper dans le nom et vous éviterez une UnsupportedCharsetException.

2. Lecture de fichiers avec encodage explicite

Ancienne méthode :

import java.io.*;
import java.nio.charset.StandardCharsets;

BufferedReader reader = new BufferedReader(
    new InputStreamReader(
        new FileInputStream("example.txt"),
        StandardCharsets.UTF_8 // <-- encodage explicitement spécifié
    )
);

Méthode moderne :

import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.io.BufferedReader;

BufferedReader reader = Files.newBufferedReader(
    Paths.get("example.txt"),
    StandardCharsets.UTF_8 // <-- encodage explicitement spécifié
);

Il est recommandé d’utiliser la deuxième méthode — elle est plus concise, plus sûre et se marie bien avec try-with-resources.

Exemple : lire une ligne à partir d’un fichier

try (BufferedReader reader = Files.newBufferedReader(
        Paths.get("hello.txt"),
        StandardCharsets.UTF_8)) {
    String line = reader.readLine();
    System.out.println("Lu: " + line);
}

Pourquoi c’est important : Si le fichier a été enregistré en UTF-8 mais que vous le lisez comme Windows-1251, les caractères cyrilliques seront déformés. En indiquant le bon encodage, le texte sera lu correctement sur n’importe quel OS.

3. Écriture de fichiers avec encodage explicite

Ancienne méthode :

import java.io.*;
import java.nio.charset.StandardCharsets;

BufferedWriter writer = new BufferedWriter(
    new OutputStreamWriter(
        new FileOutputStream("example.txt"),
        StandardCharsets.UTF_8 // <-- encodage explicitement spécifié
    )
);

Méthode moderne :

import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.io.BufferedWriter;

BufferedWriter writer = Files.newBufferedWriter(
    Paths.get("example.txt"),
    StandardCharsets.UTF_8 // <-- encodage explicitement spécifié
);

Exemple : écrire une ligne dans un fichier

try (BufferedWriter writer = Files.newBufferedWriter(
        Paths.get("hello.txt"),
        StandardCharsets.UTF_8)) {
    writer.write("Bonjour, monde !");
}

Résultat : Le fichier sera enregistré en UTF-8, et il pourra être ouvert correctement dans n’importe quel éditeur prenant en charge UTF-8.

4. Points utiles

Comment connaître les encodages pris en charge

import java.nio.charset.Charset;

public class ListCharsets {
    public static void main(String[] args) {
        System.out.println("Encodages disponibles:");
        Charset.availableCharsets().forEach((name, charset) -> System.out.println(name));
    }
}

Conseil : Si vous utilisez un encodage exotique (par exemple, pour des idéogrammes chinois anciens ou des émoticônes martiennes), vérifiez qu’il est pris en charge par votre JVM.

Utiliser try-with-resources : ne pas oublier de fermer les flux

Lorsque vous travaillez avec des fichiers, il est important de fermer les flux afin d’éviter les fuites de ressources. Le code Java moderne utilise la construction try-with-resources :

try (BufferedReader reader = Files.newBufferedReader(path, charset)) {
    // On travaille avec le fichier
}

Le flux se fermera automatiquement, même si une erreur se produit.

Recommandations

  • Mieux vaut toujours spécifier explicitement l’encodage lors de la lecture et de l’écriture de fichiers, même si vous êtes sûr que « par défaut, tout fonctionne ».
  • Utilisez UTF-8 pour les nouveaux fichiers — c’est le standard de facto, surtout si vous travaillez avec le Web, JSON, XML, ou si vous voulez que vos fichiers soient lisibles partout.
  • Pour les anciens fichiers (par exemple, une exportation depuis 1C, d’anciennes bases de données, des CSV sous Windows), utilisez l’encodage dans lequel ils ont été enregistrés (par exemple, Windows-1251, ISO-8859-1).
  • N’utilisez pas les classes obsolètes où l’encodage n’est pas défini explicitement : FileReader/FileWriter. Préférez InputStreamReader/OutputStreamWriter avec un encodage explicite ou les méthodes de Files.
  • Pour les gros fichiers, utilisez la mise en mémoire tampon (BufferedReader/BufferedWriter) afin de ne pas consommer toute la mémoire.

5. Erreurs courantes lors de la gestion des encodages

Erreur n° 1 : encodage non spécifié lors de la lecture/écriture du fichier.
Si vous ne précisez pas l’encodage, Java utilise l’encodage système par défaut ("file.encoding"). Sur votre machine, tout fonctionne, mais chez un collègue — «caractères illisibles».

Erreur n° 2 : divergence d’encodage entre lecture et écriture.
Le fichier a été écrit dans un encodage et lu dans un autre. Par exemple, le fichier a été écrit en UTF-8 et lu comme Windows-1251 — les caractères cyrilliques sont altérés.

Erreur n° 3 : utilisation des classes obsolètes FileReader/FileWriter.
Ces classes ne permettent pas de spécifier explicitement l’encodage — il est déconseillé de les utiliser. À la place, utilisez InputStreamReader/OutputStreamWriter avec un encodage indiqué ou les méthodes de Files.

Erreur n° 4 : erreur dans le nom de l’encodage.
Par exemple, vous écrivez "utf8" au lieu de "UTF-8" ou "win1251" au lieu de "Windows-1251". Java lèvera une UnsupportedCharsetException.

Erreur n° 5 : flux non fermé — le fichier n’a pas été écrit.
Si vous n’utilisez pas try-with-resources ou ne fermez pas explicitement le flux, une partie des données peut ne pas être écrite sur le disque.

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION