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

Чтение файла

Теперь добавим функциональность для чтения файла, указанного в аргументе file_path. Сначала нам понадобится пример файла для тестирования: возьмём файл с небольшим количеством текста на нескольких строках, содержащий повторяющиеся слова. В листинге 12-3 представлено стихотворение Эмили Дикинсон, которое отлично подойдёт! Создайте файл с именем poem.txt в корневой папке вашего проекта и введите стихотворение «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: Стихотворение Эмили Дикинсон служит хорошим тестовым примером.

Когда текст будет готов, отредактируйте src/main.rs и добавьте код для чтения файла, как показано в листинге 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: Чтение содержимого файла, указанного вторым аргументом

Сначала мы подключаем соответствующую часть стандартной библиотеки с помощью инструкции use: нам нужен std::fs для работы с файлами.

В main новая инструкция fs::read_to_string принимает file_path, открывает этот файл и возвращает значение типа std::io::Result<String>, содержащее содержимое файла.

После этого мы снова добавляем временную инструкцию println!, которая выводит значение contents после чтения файла, чтобы проверить, работает ли программа на данном этапе.

Запустим этот код с любой строкой в качестве первого аргумента командной строки (поскольку мы ещё не реализовали часть поиска) и файлом poem.txt в качестве второго аргумента:

$ 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!

Отлично! Код прочитал и затем вывел содержимое файла. Но у кода есть несколько недостатков. На данный момент функция main выполняет несколько обязанностей: обычно функции становятся понятнее и легче в поддержке, если каждая функция отвечает только за одну идею. Другая проблема — мы не обрабатываем ошибки так эффективно, как могли бы. Программа пока небольшая, так что эти недостатки не являются большой проблемой, но по мере роста программы исправлять их будет сложнее. При разработке программы хорошей практикой является начало рефакторинга на ранних этапах, так как рефакторить меньшие объёмы кода гораздо проще. Мы сделаем это дальше.