Working with the File System in Rust: In Practice
Rust is a modern systems language that gives the developer full control over memory while guaranteeing safety. Working with the file system is one of the basic tasks that you have to solve in almost any project. In this article, we will look at how to read and write files, manage directories, and traverse directories using practical examples. All examples are written in Rust and are ready to use.
Core Modules and Structures
In Rust, the std::fs (file system) module and std::path for working with paths handle file system operations. Key types:
std::fs::File— represents an open file.std::fs::read_dir— an iterator over the contents of a directory.std::path::Pathandstd::path::PathBuf— for working with paths.
Importing modules:
use std::fs;use std::path::Path;Reading a File Entirely
The simplest way to read a small text file is to use the fs::read_to_string function. It returns Result<String>.
use std::fs;
fn main() { let content = fs::read_to_string("example.txt") .expect("Failed to read file"); println!("File contents:{}", content);}If the file does not exist or there are no permissions, the program will panic. In real projects, use match or the ? operator for error handling.
Error Handling When Reading
use std::fs;
fn read_file(path: &str) -> Result<String, std::io::Error> { fs::read_to_string(path)}
fn main() { match read_file("config.txt") { Ok(data) => println!("{}", data), Err(e) => eprintln!("Error: {}", e), }}Writing Data to a File
For writing, use fs::write (overwrites the file) or create a File with OpenOptions.
Simple String Writing
use std::fs;
fn main() { let data = "Hello, Rust!"; fs::write("output.txt", data) .expect("Failed to write file"); println!("File written successfully");}Appending to a File
use std::fs::OpenOptions;use std::io::Write;
fn main() { let mut file = OpenOptions::new() .append(true) .create(true) .open("log.txt") .expect("Failed to open file");
writeln!(file, "{} - log entry", chrono::Local::now()) .expect("Failed to write");}Note: OpenOptions allows flexible configuration of the mode — create, overwrite, append, read.
Working with Directories
Creating, deleting, and traversing folders are common tasks. Let's look at them.
Creating a New Directory
use std::fs;
fn main() { fs::create_dir("new_folder") .expect("Failed to create folder"); // Creating nested folders (recursively) fs::create_dir_all("parent/child/grandchild") .expect("Failed to create nested folders");}Deleting a Directory
use std::fs;
fn main() { // Deleting only an empty folder fs::remove_dir("empty_folder").ok(); // Recursive deletion with all contents fs::remove_dir_all("temp_data") .expect("Failed to delete folder");}Be careful with remove_dir_all — it permanently deletes all contents.
Traversing Directory Contents
Iterating over files and folders inside a directory:
use std::fs;
fn main() { let entries = fs::read_dir(".") .expect("Failed to read directory");\