]> git.proxmox.com Git - rustc.git/blob - src/doc/book/src/ch12-02-reading-a-file.md
New upstream version 1.37.0+dfsg1
[rustc.git] / src / doc / book / src / ch12-02-reading-a-file.md
1 ## Reading a File
2
3 Now we’ll add functionality to read the file that is specified in the
4 `filename` command line argument. First, we need a sample file to test it with:
5 the best kind of file to use to make sure `minigrep` is working is one with a
6 small amount of text over multiple lines with some repeated words. Listing 12-3
7 has an Emily Dickinson poem that will work well! Create a file called
8 *poem.txt* at the root level of your project, and enter the poem “I’m Nobody!
9 Who are you?”
10
11 <span class="filename">Filename: poem.txt</span>
12
13 ```text
14 I'm nobody! Who are you?
15 Are you nobody, too?
16 Then there's a pair of us - don't tell!
17 They'd banish us, you know.
18
19 How dreary to be somebody!
20 How public, like a frog
21 To tell your name the livelong day
22 To an admiring bog!
23 ```
24
25 <span class="caption">Listing 12-3: A poem by Emily Dickinson makes a good test
26 case</span>
27
28 With the text in place, edit *src/main.rs* and add code to read the file, as
29 shown in Listing 12-4.
30
31 <span class="filename">Filename: src/main.rs</span>
32
33 ```rust,should_panic
34 use std::env;
35 use std::fs;
36
37 fn main() {
38 # let args: Vec<String> = env::args().collect();
39 #
40 # let query = &args[1];
41 # let filename = &args[2];
42 #
43 # println!("Searching for {}", query);
44 // --snip--
45 println!("In file {}", filename);
46
47 let contents = fs::read_to_string(filename)
48 .expect("Something went wrong reading the file");
49
50 println!("With text:\n{}", contents);
51 }
52 ```
53
54 <span class="caption">Listing 12-4: Reading the contents of the file specified
55 by the second argument</span>
56
57 First, we add another `use` statement to bring in a relevant part of the
58 standard library: we need `std::fs` to handle files.
59
60 In `main`, we’ve added a new statement: `fs::read_to_string` takes the
61 `filename`, opens that file, and returns a `Result<String>` of the file’s
62 contents.
63
64 After that statement, we’ve again added a temporary `println!` statement that
65 prints the value of `contents` after the file is read, so we can check that the
66 program is working so far.
67
68 Let’s run this code with any string as the first command line argument (because
69 we haven’t implemented the searching part yet) and the *poem.txt* file as the
70 second argument:
71
72 ```text
73 $ cargo run the poem.txt
74 Compiling minigrep v0.1.0 (file:///projects/minigrep)
75 Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
76 Running `target/debug/minigrep the poem.txt`
77 Searching for the
78 In file poem.txt
79 With text:
80 I'm nobody! Who are you?
81 Are you nobody, too?
82 Then there's a pair of us — don't tell!
83 They'd banish us, you know.
84
85 How dreary to be somebody!
86 How public, like a frog
87 To tell your name the livelong day
88 To an admiring bog!
89 ```
90
91 Great! The code read and then printed the contents of the file. But the code
92 has a few flaws. The `main` function has multiple responsibilities: generally,
93 functions are clearer and easier to maintain if each function is responsible
94 for only one idea. The other problem is that we’re not handling errors as well
95 as we could. The program is still small, so these flaws aren’t a big problem,
96 but as the program grows, it will be harder to fix them cleanly. It’s good
97 practice to begin refactoring early on when developing a program, because it’s
98 much easier to refactor smaller amounts of code. We’ll do that next.