File System Operations

The std.fs Module

std::fs is the standard library module for interacting with the host operating system's filesystem. It provides both one-shot convenience functions (fs::read, fs::read_to_string, fs::write, fs::copy, fs::rename) and handle-based types (File, OpenOptions, ReadDir, DirEntry, Metadata, Permissions) that wrap OS file descriptors with deterministic RAII cleanup.

Architecture of std::fs

+-----------------------------------------------------------------------+
|                       `std::fs` Public Surface                        |
|                                                                       |
|  1. One-Shot File I/O Functions:                                      |
|     - `fs::read(path)` / `fs::read_to_string(path)`                   |
|     - `fs::write(path, contents)`                                     |
|                                                                       |
|  2. Handle & Builder Types:                                           |
|     - `File` (`open`, `create`, `create_new`, `sync_all`, `set_len`)  |
|     - `OpenOptions` (`read`, `write`, `append`, `create`, `truncate`) |
|                                                                       |
|  3. Directory & Path Operations:                                      |
|     - `fs::create_dir` / `fs::create_dir_all`                         |
|     - `fs::read_dir` -> `ReadDir` -> `DirEntry`                       |
|     - `fs::remove_file` / `fs::remove_dir` / `fs::remove_dir_all`     |
|     - `fs::copy`, `fs::rename`, `fs::hard_link`, `fs::canonicalize`   |
|                                                                       |
|  4. Metadata & Permissions:                                           |
|     - `fs::metadata` / `fs::symlink_metadata` / `fs::exists`          |
|     - `Metadata`, `FileType`, `Permissions`                           |
+-----------------------------------------------------------------------+

Generic Path Parameters (P: AsRef<Path>)

Every function in std::fs that accepts a filesystem path is generic over P: AsRef<Path>. This allows callers to pass any string or path type directly without manual conversion:

  • String literals and slices (&str, "config.toml")
  • Owned strings (String, &String)
  • Path slices and owned paths (&Path, PathBuf, &PathBuf)
  • OS strings (&OsStr, OsString, Cow<'_, Path>)

Complete Overview of Free Functions in std::fs

Function Signature Behavior
fs::read(path) fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> Opens path, allocates a Vec<u8> sized from file metadata, reads all bytes, and closes the file
fs::read_to_string(path) fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> Reads entire file into a validated UTF-8 String
fs::write(path, data) fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> Creates or truncates path and writes contents in one call
fs::exists(path) fn exists<P: AsRef<Path>>(path: P) -> io::Result<bool> Checks whether path exists (returning Err on permission/loop errors rather than masking them as false!)
fs::copy(from, to) fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> Copies file contents and permissions using fast OS kernel copy (copy_file_range / fclonefileat / CopyFileEx), returning bytes copied
fs::rename(from, to) fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> Atomically renames or moves a file/directory on the same mount point
fs::canonicalize(path) fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> Resolves all . / .. components and symbolic links to an absolute PathBuf
use std::fs;
use std::io;

fn main() -> io::Result<()> {
    let dir = std::env::temp_dir();
    let src = dir.join("rust_ch50_src.txt");
    let dst = dir.join("rust_ch50_dst.txt");

    // 1. Write a file in one call:
    fs::write(&src, "std::fs overview\n")?;
    println!("src exists: {}", fs::exists(&src)?);

    // 2. Copy using OS-accelerated `fs::copy`:
    let bytes_copied = fs::copy(&src, &dst)?;
    println!("copied {} bytes to dst", bytes_copied);

    // 3. Read back as UTF-8 String:
    let content = fs::read_to_string(&dst)?;
    print!("dst content: {}", content);

    // 4. Clean up temporary files:
    fs::remove_file(&src)?;
    fs::remove_file(&dst)?;
    Ok(())
}
src exists: true
copied 17 bytes to dst
dst content: std::fs overview