Working with the File System in Rust: A Practical 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

Working with the File System in Rust: In Practice

\n\n

Rust is a modern systems programming language that combines high performance with memory safety. One of the key tasks every developer faces is working with the file system. In this article, we will use practical examples to cover how to read and write files, create directories, handle errors, and perform other file system operations in Rust.

\n\n

Core Modules for Working with the File System

\n\n

In Rust, all file system operations are concentrated in the standard library. The main modules are:

\n\n
    \n
  • std::fs — functions for working with files and directories (reading, writing, creating, deleting).
  • \n
  • std::path — working with paths (Path, PathBuf).
  • \n
  • std::io — input/output, including the Read and Write traits.
  • \n
\n\n

To get started, simply import the necessary modules:

\n\n
use std::fs;\nuse std::path::Path;\nuse std::io::prelude::*;\nuse std::fs::File;
\n\n

Reading Files in Rust

\n\n

The simplest way to read an entire file at once is to use the fs::read_to_string function. It returns a Result<String>, which allows for convenient error handling.

\n\n
use std::fs;\n\nfn main() {\n    let file_path = "example.txt";\n    \n    match fs::read_to_string(file_path) {\n        Ok(content) => println!("File contents:\\n{}", content),\n        Err(e) => eprintln!("Error reading file: {}", e),\n    }\n}
\n\n

If you need to read a file line by line (for example, for large files), use BufReader:

\n\n
use std::fs::File;\nuse std::io::{BufRead, BufReader};\n\nfn main() {\n    let file = File::open("example.txt").expect("Failed to open file");\n    let reader = BufReader::new(file);\n\n    for line in reader.lines() {\n        match line {\n            Ok(content) => println!("{}", content),\n            Err(e) => eprintln!("Error reading line: {}", e),\n        }\n    }\n}
\n\n

Writing Data to Files

\n\n

To write data to a file, use fs::write (simple string writing) or File::create followed by writing via write! or writeln!.

\n\n
use std::fs;\n\nfn main() {\n    let content = "Hello, world!\\nThis is a line to write.";\n    fs::write("output.txt", content).expect("Error writing file");\n    println!("File successfully written");\n}
\n\n

For sequential writing or appending data, use OpenOptions:

\n\n
use std::fs::OpenOptions;\nuse std::io::Write;\n\nfn main() {\n    let mut file = OpenOptions::new()\n        .append(true)  // append to file\n        .create(true)  // create if it doesn't exist\n        .open("log.txt")\n        .expect("Failed to open file");\n\n    writeln!(file, "Log entry: {}", chrono::Local::now()).expect("Error writing");\n}
\n\n

Working with Directories and Paths

\n\n

Rust provides convenient tools for creating, deleting, and traversing directories. Let's look at the basic operations.

\n\n

Creating and Deleting Directories

\n\n
use std::fs;\n\nfn main() {\n    // Create a single directory\n    fs::create_dir("new_folder").expect("Error creating directory");\n    \n    // Create nested directories (analogous to mkdir -p)\n    fs::create_dir_all("parent/child/grandchild").expect("Error creating nested directories");\n    \n    // Delete an empty directory\n    fs::remove_dir("new_folder").expect("Error deleting directory");\n    \n    // Delete a directory and all its contents\n    fs::remove_dir_all("parent").expect("Error deleting directory with contents");\n}
\n\n

Traversing Directory Contents

\n\n

To get a list of files

Blogs

Book Recommendations