Lire un fichier

Maintenant, nous allons ajouter une fonctionnalité pour lire le fichier qui est renseigné dans l'argument nom_fichier de la ligne de commande. D'abord, nous avons besoin d'un fichier d'exemple pour le tester : le meilleur type de fichier pour s'assurer que minigrep fonctionne est un fichier avec une petite quantité de texte sur plusieurs lignes avec quelques mots répétés. L'encart 12-3 présente un poème en Anglais de Emily Dickinson qui fonctionnera bien pour ce test ! Créez un fichier poem.txt à la racine de votre projet, et saisissez ce poème “I’m Nobody! Who are you?”.

Filename: poem.txt

I'm nobody! Who are you?
Are you nobody, too?
Then there's a pair of us - don't tell!
They'd banish us, you know.

How dreary to be somebody!
How public, like a frog
To tell your name the livelong day
To an admiring bog!

Encart 12-3 : Un poème Anglais d'Emily Dickinson qui fait un bon sujet d'essai

Une fois ce texte enregistré, éditez le src/main.rs et ajoutez-y le code pour lire le fichier, comme indiqué dans l'encart 12-4.

Fichier : src/main.rs

use std::env;
use std::fs;

fn main() {
    // -- partie masquée ici --
    let args: Vec<String> = env::args().collect();

    let recherche = &args[1];
    let nom_fichier = &args[2];

    println!("On recherche : {}", recherche);
    println!("Dans le fichier : {}", nom_fichier);

    let contenu = fs::read_to_string(nom_fichier)
        .expect("Quelque chose s'est mal passé lors de la lecture du fichier");

    println!("Dans le texte :\n{}", contenu);
}

Encart 12-4 : Lecture du contenu du fichier renseigné en second argument

Premièrement, nous ajoutons une autre instruction use pour importer une partie significative de la bibliothèque standard : nous avons besoin de std::fs pour manipuler les fichiers.

Dans le main, nous avons ajouté une nouvelle instruction : fs::read_to_string qui prend le nom_fichier, ouvre ce fichier, et retourne un Result<String> du contenu du fichier.

Après cette instruction, nous avons ajouté à nouveau une instruction println! qui affiche la valeur de contenu après la lecture de ce fichier, afin que nous puissions vérifier que ce programme fonctionne correctement.

Exécutons ce code avec n'importe quelle chaîne de caractères dans le premier argument de la ligne de commande (car nous n'avons pas encore implémenté la partie de recherche pour l'instant), ainsi que le fichier poem.txt en second argument :

$ cargo run the poem.txt
   Compiling minigrep v0.1.0 (file:///projects/minigrep)
    Finished dev [unoptimized + debuginfo] target(s) in 0.0s
     Running `target/debug/minigrep the poem.txt`
On recherche : the
Dans le fichier : poem.txt
Dans le texte :
I'm nobody! Who are you?
Are you nobody, too?
Then there's a pair of us - don't tell!
They'd banish us, you know.

How dreary to be somebody!
How public, like a frog
To tell your name the livelong day
To an admiring bog!

Très bien ! Notre code lit et affiche ensuite le contenu du fichier. Mais le code a quelques défauts. La fonction main a plusieurs responsabilités : généralement, les rôles des fonctions sont plus clairs et faciles à entretenir si chaque fonction est en charge d'une seule tâche. L'autre problème est que nous ne gérons pas les erreurs correctement. Le programme est encore très modeste, donc ces imperfections ne sont pas un gros problème, mais dès que le programme va grossir, il sera plus difficile de les corriger proprement. Le remaniement du code très tôt lors du développement d'un logiciel est une bonne pratique, car c'est beaucoup plus facile de remanier des petites portions de code. C'est ce que nous allons faire dès maintenant.