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