Summary - File I/O
- Rust course
- Intermediate
- Lesson 94/115
- 5 min
Combine read_to_string and write to build a log file processor.
File I/O summary
Reading: fs::read_to_string (all of it), BufReader::lines (line by line), fs::read (bytes). Writing: fs::write (overwrites), File::create + writeln!, BufWriter (bulk), append with OpenOptions. Directories: create_dir_all, read_dir, remove_dir_all. All operations return io::Result; the error kind (NotFound, PermissionDenied) is told apart with e.kind().
Save and load
Two small functions are enough for the notebook project's persistence:
fn kaydet(yol: &Path, notlar: &[&str]) -> io::Result<()> {
fs::write(yol, notlar.join("\n"))
}
fn yukle(yol: &Path) -> io::Result<Vec<String>> {
Ok(fs::read_to_string(yol)?.lines().map(String::from).collect())
}In the next step we'll use JSON instead of plain text and store structured data with serde.
Practice Persistent notes
Write the kaydet and yukle functions above. Save the notes ["süt al", "kod yaz"] in the temp folder, load them back and print with {:?}. Then try to read a non-existent file; if it's NotFound, print bulunamadı.
Starter code
use std::env;
use std::fs;
use std::io::{self, ErrorKind};
use std::path::Path;
fn main() {
// buraya yaz
}Sample solution
use std::env;
use std::fs;
use std::io::{self, ErrorKind};
use std::path::Path;
fn kaydet(yol: &Path, notlar: &[&str]) -> io::Result<()> {
fs::write(yol, notlar.join("\n"))
}
fn yukle(yol: &Path) -> io::Result<Vec<String>> {
Ok(fs::read_to_string(yol)?.lines().map(String::from).collect())
}
fn main() -> io::Result<()> {
let yol = env::temp_dir().join("notlar_ders.txt");
kaydet(&yol, &["süt al", "kod yaz"])?;
println!("{:?}", yukle(&yol)?);
match fs::read_to_string(env::temp_dir().join("hic_yok_12345.txt")) {
Err(e) if e.kind() == ErrorKind::NotFound => println!("bulunamadı"),
Err(e) => return Err(e),
Ok(_) => println!("var"),
}
Ok(())
}Expected output
["süt al", "kod yaz"] bulunamadı
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Which pattern fits continuing with defaults if the config file doesn't exist?
- Default on every error
- panic!
- Err(e) if e.kind() == ErrorKind::NotFound => default Correct answer
- unwrap()
Explanation: Swallow only the "file missing" case; other errors like permission errors should be reported to the user.
2 Error kind
Err(e) if e.____() == ErrorKind::NotFound => Vec::new(),
Err(e) if e.kind() == ErrorKind::NotFound => Vec::new(),
Explanation: io::Error::kind() gives the kind of the error.
3 Group summary
| Term | Meaning |
|---|---|
read_to_string |
Read it all |
BufReader::lines |
Line by line |
OpenOptions::append |
Append |
ErrorKind::NotFound |
File missing |