File System Operations

File.open()

std::fs::File::open(path) opens an existing file on the filesystem in read-only mode and returns io::Result<File>. It is a shorthand for OpenOptions::new().read(true).open(path).

Behavior and Error Conditions of File::open

File::open(path)
  |
  +-- File exists & readable ---> Returns `Ok(File)` positioned at byte offset `0`
  |                               (Read-only: calling `.write()` on this `File` fails!)
  +-- File does not exist ------> Returns `Err(io::Error)` with `ErrorKind::NotFound`
  +-- Insufficient permissions -> Returns `Err(io::Error)` with `ErrorKind::PermissionDenied`
Property File::open(path) Behavior
Access mode Read-only (O_RDONLY on Unix, GENERIC_READ on Windows)
Creates missing file? No (returns ErrorKind::NotFound)
Truncates existing file? No
Initial cursor offset 0 (start of file)
Descriptor inheritance across Command exec Opened with O_CLOEXEC / non-inheritable handle by default so child processes do not leak descriptors

Distinguishing ErrorKind::NotFound from Other Open Errors

When opening a configuration or cache file that may not exist on first run, match on err.kind() == io::ErrorKind::NotFound to supply a default value while still propagating permission or I/O errors:

use std::fs::{self, File};
use std::io::{self, ErrorKind, Read};
use std::path::Path;

fn read_optional_file(path: &Path) -> io::Result<Option<String>> {
    match File::open(path) {
        Ok(mut file) => {
            let mut text = String::new();
            file.read_to_string(&mut text)?;
            Ok(Some(text))
        }
        Err(err) if err.kind() == ErrorKind::NotFound => Ok(None),
        Err(err) => Err(err),
    }
}

fn main() -> io::Result<()> {
    let missing = std::env::temp_dir().join("rust_ch50_nonexistent_12345.txt");
    let existing = std::env::temp_dir().join("rust_ch50_existing.txt");

    fs::write(&existing, "found=true")?;

    println!("missing file:  {:?}", read_optional_file(&missing)?);
    println!("existing file: {:?}", read_optional_file(&existing)?);

    fs::remove_file(&existing)?;
    Ok(())
}
missing file:  None
existing file: Some("found=true")

Relative Paths Are Resolved Against the Process's Current Working Directory

Passing a relative path like File::open("data/input.csv") resolves the path relative to std::env::current_dir() (the working directory from which the process was launched)—not the directory containing the compiled binary or the .rs source file.