Rust Reading Files Basics
Reading a file loads text stored outside the program into a String the program owns. The read can fail, so the answer arrives as a Result.
Read a whole file into a String
File work lives in std::fs, short for file system. The file list.txt holds three lines — apples, bread, and milk. read_to_string reads all of it into one String:
use std::fs;
fn main() {
let text = fs::read_to_string("list.txt").expect("list.txt should be there");
print!("{}", text);
}Walk the text line by line
.lines() walks the String one line at a time. Each line arrives without its ending newline:
use std::fs;
fn main() {
let text = fs::read_to_string("list.txt").expect("list.txt should be there");
for line in text.lines() {
println!("- {}", line);
}
}Hand the failure on with ?
expect stops the program when the read fails. In a main that returns Result, ? hands the failure back to the caller instead:
use std::fs;
use std::io;
fn main() -> io::Result<()> {
let text = fs::read_to_string("list.txt")?;
println!("lines = {}", text.lines().count());
Ok(())
}A failure carries a kind
A failed read hands back an io::Error. Its kind names the broad reason. This file is not there at all:
use std::fs;
fn main() {
match fs::read_to_string("missing.txt") {
Ok(text) => println!("read {} letters", text.len()),
Err(e) => println!("kind = {:?}", e.kind()),
}
}Example
use std::fs;
use std::io;
fn main() -> io::Result<()> {
let text = fs::read_to_string("list.txt")?;
let mut longest = "";
for line in text.lines() {
if line.len() > longest.len() {
longest = line;
}
}
println!("items = {}", text.lines().count());
println!("longest = {} ({} letters)", longest, longest.len());
Ok(())
}Key points
- Reading brings outside text in as a value the program owns.
- read_to_string reads the whole file at once, into one String.
- A file read returns a Result, because the file might be missing or unreadable.
- .lines() walks a String one line at a time, without the newline characters.
- A failed read is an io::Error, and its kind() names the broad reason.
In this example, main returns an io::Result, so the ? after read_to_string can hand a failure to the caller. The file list.txt holds three lines: apples, bread, and milk. The loop walks text.lines() and keeps the longest line it sees. apples wins at six letters. The last lines print the count of items and the longest line. Rust Reading Files, in the Intermediate course, goes deeper from here — reading a file in pieces, and working with paths.
Note
A plain file name is looked up in the folder the program runs from, not the folder holding the code.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
fs::read_to_string is called on a file that is not there. What comes back?