读取文件
现在,我们将添加读取 file_path
中指定的文件的功能
论点。首先,我们需要一个示例文件来测试它:我们将使用一个带有
多行少量文本,带有一些重复的单词。示例 12-3
有一首艾米莉·狄金森 (Emily Dickinson) 的诗会很有效!创建一个名为
poem.txt项目的根级别,然后输入诗歌“I'm Nobody!你是谁?
文件名: 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:Emily Dickinson 的一首诗就是一个很好的测试案例。
文本就位后,编辑 src/main.rs 并添加代码来读取文件,如示例 12-4 所示。
文件名: 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}");
}
示例 12-4:读取第二个参数指定的文件内容
首先,我们引入标准库的相关部分,并使用
statement: 我们需要 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
函数具有多重职责:通常,如果每个函数只负责一个 idea,则函数会更清晰、更容易维护。另一个问题是我们没有尽可能好地处理错误。该程序仍然很小,因此这些缺陷不是什么大问题,但随着程序的发展,将更难干净地修复它们。在开发程序时,最好尽早开始重构,因为重构少量代码要容易得多。我们接下来会这样做。