Working with the File System in Rust: A Complete Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to Working with the File System in Rust

Rust is a modern systems programming language that offers powerful and safe tools for interacting with the file system. Unlike many other languages, Rust guarantees memory and thread safety, which is especially important for input/output operations. In this article, we will thoroughly examine how to create, read, write files and directories, manage paths, and handle errors using the standard library std::fs and std::path.

The material will be useful both for beginners who are just getting acquainted with Rust and for experienced developers looking to refresh their knowledge. All code examples are ready to run and are accompanied by comments.



Main Modules and Imports

Two key modules are used for working with the file system in Rust:

  • std::fs — provides functions for operations with files and folders (reading, writing, deleting, copying, etc.).
  • std::path — contains the Path and PathBuf types for working with paths.

For most tasks, it is enough to add the following imports:

use std::fs;use std::path::Path;use std::io::prelude::*; // for working with streams


Working with Files: Reading and Writing

Reading File Contents

The simplest way to read an entire file into a string is to use the fs::read_to_string function. It returns a Result<String>, so you need to handle a possible error.

use std::fs;

fn read_file(path: &str) -> Result<String, std::io::Error> { let content = fs::read_to_string(path)?; Ok(content)}

fn main() { match read_file("example.txt") { Ok(text) => println!("File contents:{}", text), Err(e) => eprintln!("Read error: {}", e), }}

If you need to read a file as binary data, use fs::read, which returns Vec<u8>.



Writing to a File

To write a string to a file, use fs::write. It will create the file if it does not exist, or overwrite an existing one.

use std::fs;

fn write_file(path: &str, content: &str) -> Result<(), std::io::Error> { fs::write(path, content)?; println!("File successfully written"); Ok(())}

fn main() { let data = "Hello, Rust!Second line."; if let Err(e) = write_file("output.txt", data) { eprintln!("Write error: {}", e); }}

For appending to the end of a file or more fine-grained control, use OpenOptions:

use std::fs::OpenOptions;use std::io::Write;

fn append_to_file(path: &str, line: &str) -> Result<(), std::io::Error> { let mut file = OpenOptions::new() .append(true) .create(true) .open(path)?; writeln!(file, "{}", line)?; Ok(())}


Working with Directories

Creating and Deleting Folders

To create a directory, use fs::create_dir (single folder) or fs::create_dir_all (recursively, like mkdir -p).

use std::fs;

fn main() -> Result<(), std::io::Error> { // Creating a single folder fs::create_dir("my_folder")?;

// Recursively creating nested folders fs::create_dir_all("data/subdir/logs")?;

// Deleting an empty folder fs::remove_dir("my_folder")?;

// Recursively deleting a folder with all its contents fs::remove_dir_all("data")?;

Ok(())}


Reading Directory Contents

The fs::read_dir function returns an iterator over the entries of a directory. Each entry is a DirEntry, from which you can get the name, type, and metadata.

use std::fs;

fn list_directory(path:

Blogs

Book Recommendations