Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Leggere un File

Ora aggiungeremo la funzionalità per leggere il file specificato nell’argomento percorso_file . Per prima cosa abbiamo bisogno di un file di esempio con cui testarlo: useremo un file con una piccola quantità di testo su più righe con alcune parole ripetute. Il Listato 12-3 contiene una poesia di Emily Dickinson che funzionerà bene! Crea un file chiamato poesia.txt nella radice del tuo progetto e inserisci la poesia “Io sono Nessuno! Tu chi sei?”

File: poesia.txt
Io sono Nessuno! Tu chi sei?
Sei Nessuno anche tu?
Allora siamo in due!
Non dirlo! Potrebbero spargere la voce!

Che grande peso essere Qualcuno!
Così volgare — come una rana
che gracida il tuo nome — tutto giugno —
ad un pantano in estasi di lei!
Listato 12-3: Una poesia di Emily Dickinson è un buon caso di test

Con il testo inserito, modifica src/main.rs e aggiungi il codice per leggere il file, come mostrato nel Listato 12-4.

File: src/main.rs
use std::env;
use std::fs;

fn main() {
    // --taglio--
    let args: Vec<String> = env::args().collect();

    let query = &args[1];
    let percorso_file = &args[2];

    println!("Cerco {query}");
    println!("Nel file {percorso_file}");

    let contenuto = fs::read_to_string(percorso_file)
        .expect("Dovrebbe essere stato possibile leggere il file");

    println!("Con il testo:\n{contenuto}");
}
Listato 12-4: Lettura del contenuto del file specificato dal secondo argomento

Per prima cosa introduciamo una parte rilevante della libreria standard con un’istruzione use: abbiamo bisogno di std::fs per gestire i file.

In main, la nuova istruzione fs::read_to_string prende percorso_file, apre quel file e restituisce un valore di type std::io::Result<String> che contiene il contenuto del file.

Dopodiché, aggiungiamo di nuovo un’istruzione temporanea println! che stampa il valore di contenuto dopo la lettura del file, in modo da poter verificare che il programma funzioni correttamente.

Eseguiamo questo codice con una stringa qualsiasi come primo argomento della riga di comando (perché non abbiamo ancora implementato la parte di ricerca) e il file poesia.txt come secondo argomento:

$ cargo run -- ciao poesia.txt
   Compiling minigrep v0.1.0 (file:///progetti/minigrep)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s
     Running `target/debug/minigrep ciao poesia.txt`
Cerco ciao
Nel file poesia.txt
Con il testo:
Io sono Nessuno! Tu chi sei?
Sei Nessuno anche tu?
Allora siamo in due!
Non dirlo! Potrebbero spargere la voce!

Che grande peso essere Qualcuno!
Così volgare — come una rana
che gracida il tuo nome — tutto giugno —
ad un pantano in estasi di lei!

Ottimo! Il codice ha letto e poi stampato il contenuto del file. Ma il codice presenta alcuni difetti. Al momento, la funzione main ha più responsabilità: in genere, le funzioni sono più chiare e facili da gestire se ogni funzione è responsabile di una sola idea. L’altro problema è che non gestiamo gli errori al meglio delle nostre possibilità. Il programma è ancora piccolo, quindi questi difetti non rappresentano un grosso problema, ma man mano che il programma cresce, sarà più difficile correggerli in modo pulito. È buona norma iniziare il refactoring fin dall’inizio quando si sviluppa un programma, perché è molto più facile risistemare piccole quantità di codice. Lo faremo come prossima cosa.