Without data persistence, programs have limited usefulness. With files, we can store data, and persist data from memory for next time.
We can implement file handling directly with low-level types, but things like BufReader
can simplify this. BufReader
helps with reading lines, and reading entire files.
To begin, consider this example—perform the steps necessary to read in a file on the disk. We then print out its contents to the screen.
open()
. Please change the path to one that exists on your computer—any text file will do.BufReader
we created from the file. We call lines()
and print each line in a for
-loop.use std::io::*; use std::fs::File; fn main() { // Step 1: open and unwrap a file. let file = File::open("/home/sam/programs/test.txt").unwrap(); let reader = BufReader::new(file); // Step 2: loop over lines and print them. for line in reader.lines() { println!("LINE: {}", line.unwrap()); } }LINE: Hello LINE: friends
This example uses the read_until
function on BufReader
. It gets the entire contents of the file, and places it into a vector of bytes.
byte
vector, we can get a string
representation with String
from_utf8
.byte
representation shown.use std::io::*; use std::fs::File; fn main() { let file = File::open("/home/sam/programs/test.txt").unwrap(); let mut reader = BufReader::new(file); let mut buf = vec![]; // Use read_until to read until EOF. reader.read_until(u8::MIN, &mut buf); println!("BYTES: {:?}", buf); // Convert vector of bytes to string. let data = String::from_utf8(buf).unwrap(); println!("STRING: {}", data); }BYTES: [111, 114, 97, 110, 103, 101, 32, 99, 97, 116, 13, 10] STRING: orange cat
To see if a file exists, we can use the Path
type and call exists()
on it. Here we check a file that does not exist, and one that exists on the test system.
use std::path::Path; fn main() { // Check that this file does not exist. if !Path::new("/Users/sam/missing").exists() { println!("NOT FOUND"); } // This file exists. if Path::new("/Users/sam/example.txt").exists() { println!("FOUND"); } }NOT FOUND FOUND
File handling in Rust is done in a similar way to many other languages. We can handle byte
data, and then convert it to strings. And functions like lines()
on BufReader
are helpful.