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

Lendo um arquivo

Agora vamos adicionar funcionalidade para ler o arquivo especificado no argumento file_path. Primeiro, precisamos de um arquivo de exemplo para testar: usaremos um arquivo com uma pequena quantidade de texto distribuída em várias linhas e com algumas palavras repetidas. A Listagem 12-3 traz um poema de Emily Dickinson que funciona muito bem para isso! Crie um arquivo chamado poem.txt na raiz do seu projeto e coloque nele o poema “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!
Listing 12-3: Um poema de Emily Dickinson é um bom caso de teste

Com o texto no lugar, edite src/main.rs e adicione o código para ler o arquivo, como mostrado na Listagem 12-4.

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

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

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

    println!("Searching for {query}");
    println!("In file {file_path}");

    let contents = fs::read_to_string(file_path)
        .expect("Should have been able to read the file");

    println!("With text:\n{contents}");
}
Listing 12-4: Lendo o conteúdo do arquivo especificado pelo segundo argumento

Primeiro, trazemos uma parte relevante da biblioteca padrão com uma instrução use: precisamos de std::fs para lidar com arquivos.

Em main, a nova chamada fs::read_to_string recebe file_path, abre o arquivo e retorna um valor do tipo std::io::Result<String> contendo seu conteúdo.

Depois disso, adicionamos novamente uma instrução println! temporária que imprime o valor de contents após a leitura do arquivo, para que possamos confirmar que o programa está funcionando até aqui.

Vamos executar esse código com qualquer string como primeiro argumento da linha de comando, porque ainda não implementamos a parte da busca, e com o arquivo poem.txt como segundo argumento:

$ cargo run -- the poem.txt
   Compiling minigrep v0.1.0 (file:///projects/minigrep)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s
     Running `target/debug/minigrep the poem.txt`
Searching for the
In file poem.txt
With text:
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!

Ótimo! O código leu e depois imprimiu o conteúdo do arquivo. Mas ele tem alguns problemas. Neste momento, a função main tem responsabilidades demais. Em geral, funções são mais claras e mais fáceis de manter quando cada uma é responsável por apenas uma ideia. O outro problema é que ainda não estamos tratando erros tão bem quanto poderíamos. O programa ainda é pequeno, então essas falhas não são graves, mas, à medida que ele crescer, será mais difícil corrigi-las de forma limpa. Uma boa prática é começar a refatorar cedo no desenvolvimento, porque é muito mais fácil refatorar pequenas quantidades de código. É isso que faremos a seguir.