CodeBlanks Logo Icon CodeBlanks

Summary - File I/O

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

main.rs
use std::env;
use std::fs;
use std::io::{self, ErrorKind};
use std::path::Path;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
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

Question
Err(e) if e.____() == ErrorKind::NotFound => Vec::new(),
Answer
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

All lessons in Intermediate