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
Create without overwrite
The created file receives the report bytes.
Create without overwriteWrite and read report
Dropping the handle closes it before the path is read again.
Write and read reportRemove the temporary path
The temporary report prints once, then its path is removed.
Remove the temporary path
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: 80Follow 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
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.