ProgramGuru

Files and I/O errors

Files and I/O errors

A school report may need to be saved and loaded later. File operations can fail because of permissions, missing paths or storage problems. Rust represents these failures through Result so the caller can handle them rather than assuming a successful environment.

What you’ll learn

  • Save and read UTF-8 report data with explicit I/O errors.
  • Explain overwrite protection and cleanup limitations.

Files and I/O errors in action

  1. Create without overwrite

    The created file receives the report bytes.

    Create without overwrite
  2. Write and read report

    Dropping the handle closes it before the path is read again.

    Write and read report
  3. Remove the temporary path

    The temporary report prints once, then its path is removed.

    Remove the temporary path
The created file receives the report bytes. Dropping the handle closes it before the path is read again. The temporary report prints once, then its path is removed. The stored result permits cleanup even if the write or read returned an ordinary I/O error.

Files and I/O errors explained

The example creates a temporary file using create_new, which refuses to overwrite an existing file at that path. write_all writes all supplied bytes or returns an error. read_to_string expects valid UTF-8. Paths are platform values rather than assumptions about one fixed directory separator.

Work through the Rust program

Save the complete source as main.rs in the Rust environment. No standard input is needed.

Rust 2024 · complete program

use std::{fs, io::{self, Write}};
fn main() -> io::Result<()> {
  let path = std::env::temp_dir().join(format!("programguru-rust-{}.txt", std::process::id()));
  let mut file = fs::OpenOptions::new().write(true).create_new(true).open(&path)?;
  let result = (|| -> io::Result<()> {
    file.write_all(b"Diya: 80\n")?;
    drop(file);
    let report = fs::read_to_string(&path)?;
    print!("{report}");
    Ok(())
  })();
  fs::remove_file(&path)?;
  result
}

Expected output

Diya: 80

Follow the execution

The created file receives the report bytes. Dropping the handle closes it before the path is read again. The temporary report prints once, then its path is removed. The stored result permits cleanup even if the write or read returned an ordinary I/O error.

Try a small variation

Your task: Why use create_new rather than silently overwriting an existing temporary path?

Rust 2024 · complete program

use std::{fs, io::{self, Write}};
fn main() -> io::Result<()> {
  let path = std::env::temp_dir().join(format!("programguru-rust-{}.txt", std::process::id()));
  let mut file = fs::OpenOptions::new().write(true).create_new(true).open(&path)?;
  let result = (|| -> io::Result<()> {
    file.write_all(b"Diya: 80\n")?;
    drop(file);
    let report = fs::read_to_string(&path)?;
    print!("{report}");
    Ok(())
  })();
  fs::remove_file(&path)?;
  result
}

Worked answer

It rejects an existing path and protects its contents from accidental replacement. The application must then report or handle that creation failure.

Mistakes and limits to recognize

This is local file work; browser sandboxes may not permit it. The example is not a secure general-purpose temporary-file library or an atomic production save protocol. Cleanup can also fail, and sudden process termination is outside the ordinary Result cleanup path.

API details: official Rust documentation for this boundary.

Check your understanding

Why use create_new rather than silently overwriting an existing temporary path?
Choose one answer. You can try again.

Answer and explanation

It rejects an existing path and protects its contents from accidental replacement.

It rejects an existing path and protects its contents from accidental replacement. The application must then report or handle that creation failure.

Take the idea into your next program

It rejects an existing path and protects its contents from accidental replacement. The application must then report or handle that creation failure. This is local file work; browser sandboxes may not permit it.

Further reading: the official Rust Book on files and i/o errors.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Cargo packages and dependencies →