CodeGym /Cours /JAVA 25 SELF /Lecture de fichiers texte : ligne par ligne ou en en...

Lecture de fichiers texte : ligne par ligne ou en entier

JAVA 25 SELF
Niveau 36, Leçon 1
Disponible

1. Lecture du fichier ligne par ligne : BufferedReader et compagnie

Nous avons déjà abordé la lecture octet par octet : c’est pratique pour les formats binaires, mais pour le texte cette approche n’est pas idéale. Un fichier texte est composé de caractères qui dépendent de l’encodage. Java propose donc des « surcouches » — FileReader, BufferedReader et d’autres classes — qui transforment un flux d’octets en flux de caractères et de lignes.

Imaginez un fichier texte — qu’il s’agisse du journal d’exécution d’un programme, d’une liste d’utilisateurs ou même du roman fleuve « Guerre et Paix ». Parfois, il faut lire rapidement tout le fichier d’un coup, parfois le parcourir ligne par ligne, et parfois extraire une ligne précise.

En Java, plusieurs méthodes existent, et le choix dépend de la taille du fichier et de la tâche. Si vous devez traiter le fichier ligne par ligne (par exemple compter le nombre de lignes ou trouver une entrée), utilisez la lecture ligne par ligne. Et si le fichier est petit, vous pouvez le charger entièrement en mémoire et travailler avec comme avec une liste de lignes.

Pourquoi la lecture ligne par ligne est-elle une bonne idée ?

Pour les gros fichiers, la lecture ligne par ligne évite les problèmes de mémoire. Charger en mémoire un journal de plusieurs gigaoctets est une mauvaise idée : vous risquez de tomber sur une OutOfMemoryError. En revanche, lire le fichier ligne après ligne est peu coûteux, même s’il pèse des centaines de mégaoctets.

Comment faire en Java ?

La méthode la plus classique consiste à utiliser BufferedReader (ou ses proches) et la méthode readLine().

import java.io.*;

public class ReadLinesDemo {
    public static void main(String[] args) {
        String fileName = "example.txt";

        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            String line;
            int lineNumber = 1;
            while ((line = reader.readLine()) != null) {
                System.out.printf("%3d: %s%n", lineNumber, line);
                lineNumber++;
            }
        } catch (IOException e) {
            System.out.println("Erreur lors de la lecture du fichier: " + e.getMessage());
        }
    }
}

Ici, nous ouvrons le fichier en lecture et, avec readLine(), nous lisons une ligne à la fois jusqu’à la fin (null). Ensuite, nous affichons chaque ligne avec son numéro.

En bref sur try-with-resources

Voyez-vous la construction try (...) { ... } ? C’est try-with-resources. Elle garantit que le fichier sera fermé, même si une erreur survient en cours de lecture. Vous n’avez pas à appeler close() manuellement : la fermeture se produira automatiquement, même avec catch/finally.

Pourquoi utiliser BufferedReader ?

BufferedReader ne lit pas caractère par caractère, mais par blocs (généralement de 8192 octets), ce qui accélère le travail avec les fichiers. De plus, il possède la méthode pratique readLine(), qui retourne la ligne jusqu’au caractère de fin de ligne.

Quelle taille de tampon choisir ?

En général, BufferedReader utilise un tampon de 8192 octets (8 Ko) — suffisant pour la plupart des cas. Si vous lisez des lignes très longues (par exemple 100_000 caractères), vous pouvez augmenter le tampon :

BufferedReader reader = new BufferedReader(new FileReader(fileName), 65536); // tampon de 64 Ko

Mais pour les tâches ordinaires, la taille par défaut convient parfaitement.

2. Lecture du fichier en entier : Files.readAllLines et Files.readString

Si le fichier est petit (par exemple jusqu’à 10–20 Mo), il est pratique de le charger en entier. Par exemple, si vous devez rapidement obtenir la liste de toutes les lignes, analyser le texte ou l’envoyer sur le réseau.

Approche moderne : Files.readAllLines

Depuis Java 7, la classe Files propose de nombreuses méthodes utiles.

import java.nio.file.*;
import java.io.IOException;
import java.util.List;

public class ReadAllLinesDemo {
    public static void main(String[] args) {
        Path path = Path.of("example.txt");

        try {
            List<String> lines = Files.readAllLines(path);
            for (int i = 0; i < lines.size(); i++) {
                System.out.printf("%3d: %s%n", i + 1, lines.get(i));
            }
        } catch (IOException e) {
            System.out.println("Erreur lors de la lecture du fichier: " + e.getMessage());
        }
    }
}

Ici, la méthode Files.readAllLines(path) renvoie une liste de lignes (List<String>). Vous pouvez manipuler cette liste comme une collection ordinaire : rechercher, trier, filtrer.

Encore plus moderne : Files.readString (Java 11+)

Si vous devez obtenir tout le fichier dans une seule chaîne (par exemple pour rechercher une sous-chaîne ou l’envoyer en JSON), utilisez Files.readString :

import java.nio.file.*;
import java.io.IOException;

public class ReadStringDemo {
    public static void main(String[] args) {
        Path path = Path.of("example.txt");

        try {
            String content = Files.readString(path);
            System.out.println("Contenu du fichier:");
            System.out.println(content);
        } catch (IOException e) {
            System.out.println("Erreur lors de la lecture du fichier: " + e.getMessage());
        }
    }
}

Et l’encodage ?

Par défaut, les méthodes Files.readAllLines et Files.readString utilisent l’encodage standard de votre système. Si le fichier a été enregistré dans un autre encodage (par exemple Windows-1251), indiquez-le explicitement :

List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
String content = Files.readString(path, StandardCharsets.UTF_8);

3. Comparaison des approches : quand utiliser laquelle

Approche Quand l’utiliser Avantages Inconvénients
BufferedReader.readLine()
Grands fichiers, traitement ligne par ligne Économe en mémoire, flexible Lecture uniquement ligne par ligne
Files.readAllLines()
Petits et moyens fichiers Renvoie directement une liste de lignes, simple Pour les gros fichiers — OutOfMemory
Files.readString()
Petits fichiers, besoin de tout le texte Texte complet en une seule chaîne Pas de découpage en lignes

Recommandation:
— Si le fichier est petit, utilisez Files.readAllLines ou Files.readString.
— Si le fichier est volumineux ou si vous ne connaissez pas sa taille, utilisez BufferedReader.readLine().

4. Tâches pratiques : exemples et analyse

Exemple 1. Comptage des lignes dans un gros fichier

Supposons que vous deviez connaître le nombre de lignes dans un fichier volumineux (par exemple, un journal de serveur).

import java.io.*;

public class LineCount {
    public static void main(String[] args) {
        String fileName = "biglog.txt";
        int lineCount = 0;

        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            while (reader.readLine() != null) {
                lineCount++;
            }
            System.out.println("Nombre total de lignes dans le fichier: " + lineCount);
        } catch (IOException e) {
            System.out.println("Erreur lors de la lecture du fichier: " + e.getMessage());
        }
    }
}

Exemple 2. Recherche de lignes par contenu

Recherchons toutes les lignes contenant le mot « erreur » (insensible à la casse) :

import java.io.*;

public class FindErrorLines {
    public static void main(String[] args) {
        String fileName = "biglog.txt";
        String keyword = "erreur";

        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            String line;
            int lineNumber = 1;
            while ((line = reader.readLine()) != null) {
                if (line.toLowerCase().contains(keyword)) {
                    System.out.printf("%3d: %s%n", lineNumber, line);
                }
                lineNumber++;
            }
        } catch (IOException e) {
            System.out.println("Erreur lors de la lecture du fichier: " + e.getMessage());
        }
    }
}

Exemple 3. Chargement d’une configuration depuis un petit fichier

Fichier config.txt :

host=localhost
port=8080
mode=dev

Nous le lisons en entier et l’analysons en paires clé-valeur :

import java.nio.file.*;
import java.util.*;

public class ConfigLoader {
    public static void main(String[] args) throws Exception {
        Path path = Path.of("config.txt");
        List<String> lines = Files.readAllLines(path);

        Map<String, String> config = new HashMap<>();
        for (String line : lines) {
            if (line.trim().isEmpty() || line.startsWith("#")) continue; // on ignore les lignes vides et les commentaires
            String[] parts = line.split("=", 2);
            if (parts.length == 2) {
                config.put(parts[0].trim(), parts[1].trim());
            }
        }

        System.out.println("Configuration chargée: " + config);
    }
}

5. Erreurs courantes lors de la lecture de fichiers texte

Erreur n°1: Tenter de lire un fichier binaire comme un fichier texte. Si vous ouvrez une image ou une archive avec BufferedReader ou Files.readAllLines, vous obtiendrez des caractères incohérents et vous risquez une OutOfMemoryError. Pour les fichiers binaires, utilisez InputStream !

Erreur n°2: Ne pas gérer les exceptions. Les fichiers peuvent être supprimés, déplacés, verrouillés. Enveloppez toujours la lecture dans un bloc try-catch et informez l’utilisateur en cas de problème.

Erreur n°3: Ignorer l’encodage. Si votre texte est en russe et que vous lisez le fichier sans spécifier l’encodage, vous pouvez obtenir « ????? ». Utilisez StandardCharsets.UTF_8 ou l’encodage nécessaire.

Erreur n°4: Oublier de fermer le flux. Si vous ne fermez pas le fichier, il peut rester verrouillé jusqu’à la fin du programme. Utilisez toujours try-with-resources.

Erreur n°5: Utiliser read() au lieu de readLine() pour les fichiers texte. La méthode read() lit caractère par caractère — c’est lent et peu pratique pour des lignes. Pour le texte, utilisez readLine() ou les méthodes de la classe Files.

1
Mission
JAVA 25 SELF, niveau 36, leçon 1
Bloqué
Assemblage des fragments de la grande saga 📖
Assemblage des fragments de la grande saga 📖
1
Mission
JAVA 25 SELF, niveau 36, leçon 1
Bloqué
Recherche de secrets communs dans des dossiers d'espionnage 🕵️
Recherche de secrets communs dans des dossiers d'espionnage 🕵️
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION