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?» («Я — никто! А ты кто?»).

Файл: 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!
Листинг 12-3: Стихотворение Эмили Дикинсон — хороший материал для тестов

Текст на месте — теперь отредактируйте src/main.rs и добавьте код чтения файла, как в листинге 12-4.

Файл: src/main.rs
use std::env;
use std::fs;

fn main() {
    // --пропуск--
    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}");
}
Листинг 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 несколько обязанностей, а функции обычно понятнее и проще в поддержке, если каждая отвечает только за что-то одно. Другая проблема — мы обрабатываем ошибки не так хорошо, как могли бы. Программа пока маленькая, и эти недостатки не страшны, но по мере её роста исправлять их аккуратно будет всё труднее. Рефакторинг лучше начинать на ранних этапах разработки: маленький объём кода переделывать гораздо проще. Этим мы сейчас и займёмся.