Reading and Writing Files in Rust: A Step-by-Sep Guide

1. Overview

Reading from and writing to files is a common task in the programming world. Rust standard library provides functions to work with files.

In this tutorial, we’ll delve into the basics of file operations in Rust, covering reading, writing, and appending data to files.

2. Initial Setup

Let’s create a new project called file_io:

cargo new file_io

Next, let’s open the project with an IDE/editor of choice. Since Rust provides functions to work with files in its standard library, we don’t need any external crate.

Finally, we’ll work with a text file named “world.txt” placed in the project’s root directory, containing the text: “Humanity should be the goal of politics”.

3. Reading From a File

To read the content of a file, Rust provides the std::fs::read_to_string() function to simply read the content of a file. Here’s a simple example that uses the function to read a file:

let content = fs::read_to_string("world.txt").expect("Could not read file");
println!("File content: {}", content);

In the code above, the fs::read_to_string() function reads the file “world.txt” and returns a Result<String>. If the operation is successful, it returns Ok(String) i.e., the content of the file. Otherwise, it returns Err. The expected methods help to handle a potential error since the function we are working with returns a Result.

Here’s the output of the sample code:

The code compiles without any error and outputs the expected content of the file.

4. Writing to a File

Rust provides std::fs::write function to write to a file. Here’s an example code to write content to a file:

let content_write = "Humanity should be the goal of politics";
fs::write("humanity.txt", content_write) .expect("Could not write to file");

Here, we use the fs::write function which takes two arguments: the path to the file and the content to write. The function also returns a Result<()>. If the operation is successful, it returns Ok(()) and saves the file to the specified path. Otherwise, it returns Err.

5. Reading From Files Line by Line

In a case of a very large file, we may decide to read the file line by line. Rust provides a BufReader function for buffered reading. BufReader can improve performance when working with large files.

Here’s a simple code that read the content of a file line by line:

let path = Path::new("file.txt");
let file = File::open(&path).expect("file not found");
let reader = io::BufReader::new(file);
for line in reader.lines() {
    let line = line.expect("Could not read file");
    println!("{}", line);
}

First, we specify the location of the file. Next, we open the file and read its content. Finally, we output every line in the document to the console.

Notably, this function also returns the Result and we handle possible errors with expect().

6. Writing to File Line by Line

Interestingly, we can write to file line by line using the writeln!() macro. Here’s an example code showing how to write to a file line by line:

let mut file_write = File::create("movie.txt").expect("Cannot create file");
writeln!(file_write, "Games of throne").expect("Cannot write to file");
writeln!(file_write, "Harry Potten").expect("Cannot write to file");

In the code above, we create a movie.txt file to which the list of movies will be written. Then, we use the writeln!() macro to write to the file line by line.

Finally, we handle possible errors.

7. Appending to an Open File

Appending to an open file is a common operation in Rust.  We may decide to flip through pages of a document and write its content into a file. We need to keep the file open and append to it to avoid overwriting already written content.

We can use the OpenOptions struct from the std::fs module to open a file in append mode.

Here’s an example to use OpenOptions :


 let mut file = OpenOptions::new()
     .write(true)
     .append(true)
     .create(true)
     .open("number.txt").expect("Cannot write to file");
for i in 1..6 {
    writeln!(file, "Appending line number {}", i).expect("Cannot write to file");
}

Here, we create a new file if the file is not existing. Next, we enable functionality to write, keep the file open and append to the file while it’s open.

8. Conclusion

In this article, we learned how to work with files in Rust with a focus on writing to and reading from a file. Additionally, we explore different examples to see file writing and file reading operations.

The source code for the examples is available on GitHub.