This tutorial will go through how to read and write to a file for Rust version 1.26+ and Rust version 1.0.
Table of contents
Read a File to String in Rust 1.26+
Rust provides straight-forward one-line functions for reading and writing. To read a file to string, we can use the std::fs::read_to_string()
method. We have to specify the path to the file. Let’s look at an example of reading the host database under /etc/hosts
:
fn main() { let info_str = std::fs::read_to_string("/etc/hosts").expect("File not able to be read"); println!("{}", info_str); }
We use expect()
in the above code and the following examples to raise an exception method if the thread panics.
## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost
Read a File to String in Rust 1.0
In Rust 1.0, reading and writing to file is more verbose than the one-line functions. We still use the read_to_string() method, but we have to allocate a String
or Vec
before calling the method. This form is handy because we can reuse the allocated data or append it to an existing object. Let’s look at an example
use std::fs::File; use std::io::Read; fn main() { let mut info_str = String::new(); let mut f = File::open("/etc/hosts").expect("Unable to open file"); f.read_to_string(&mut info_str).expect("Unable to read string"); println!("{}", info_str); }
## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost
Read a File to Vec<u8> in Rust 1.26+
To read a file to a Vec<u8>
we can use the std::fs::read()
method which accepts the path to the file as a parameter. We can convert the Vec<u8>
object to a String
using String::from_utf8_loss()
method. Let’s look at an example.
fn main() { let info_vec = &std::fs::read("/etc/hosts").expect("The file could not be read"); println!("{}", info_vec.len()); let info_str = String::from_utf8_lossy(info_vec); println!("{}", info_str); }
365 ## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost
Read a File to Vec<u8> in Rust 1.0
For Rust 1.0, we have to allocate a Vec
and open the file in read-only mode using File::open
. Then we can call the read_to_end()
method on the file object to read all the bytes until the end of the file and place them into the Vec
. Let’s look at an example:
use std::fs::File; use std::io::Read; fn main() { let mut data = Vec::new(); let mut f = File::open("/etc/hosts").expect("Unable to open file"); f.read_to_end(&mut data).expect("Unable to read data"); println!("{}", data.len()); let info_string = String::from_utf8_lossy(&data); println!("{}", info_string); }
365 ## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost
Write a File in Rust 1.26+
To write to a file in Rust 1.26+, we can the use std::fs::write()
method. We have to specify the path to the file and the string we want to write to the file. Let’s look at an example:
fn main() { let data = "Rust\nis\nfun\nto\nlearn!"; std:fs::write("write_test.txt", data).expect("Unable to write file"); }
Write a File in Rust 1.0
We can use the Write trait to write to a file in Rust 1.0. The write_all()
method writes out data to file as bytes. We can convert a String
/&str
to bytes with as_bytes
. Let’s look at an example:
use std::fs::File; use std::io::Write; fn main() { let data = "Rust\nis\nfun\nto\nlearn!"; let path = "write_test.txt"; let mut f = File::create(path).expect("Unable to create file"); f.write_all(data.as_bytes()).expect("Unable to write data"); }
Buffered I/O
BufReader
Using a Read
instance can be inefficient. For example, every call to read on TcpStream
results in a system call.
A BufReader
can improve the speed of programs that make small and repeated read calls to the same file or network socket.
However, read_to_end()
copies data in large chunks, so the transfer may require fewer I/O requests than BufReader
.
Let’s look at an example of using BufReader
.
use std::fs::File; use std::io::{BufReader, Read}; fn main() { let mut data = String::new(); let f = File::open("/etc/hosts").expect("Unable to open file"); let mut br = BufReader::new(f); br.read_to_string(&mut data).expect("Unable to read string"); println!("{}", data); }
We can also use BufReader
to read the file line-by-line. Let’s look at an example to print the lines to the console.
use std::fs::File; use std::io::{BufRead, BufReader}; fn main() { let f = File::open("/etc/hosts").expect("Unable to open file"); let fb = BufReader::new(f); for line in fb.lines() { let line = line.expect("Unable to read line"); println!("Line: {}", line); } }
Line: ## Line: # Host Database Line: # Line: # localhost is used to configure the loopback interface Line: # when the system is booting. Do not change this entry. Line: ## Line: 127.0.0.1 localhost Line: 255.255.255.255 broadcasthost Line: ::1 localhost
BufWriter
Let’s look at an example of using the BufWriter
to write to a file using write_all()
. The method will continuously call write()
until there is no more data to write. We always have to write the data as bytes. We can convert a String
/&str
to bytes using as_bytes
.
use std::fs::File; use std::io::{BufWriter, Write}; fn main() { let data = "Some data!"; let f = File::create("/tmp/foo").expect("Unable to create file"); let mut fb = BufWriter::new(f); fb.write_all(data.as_bytes()).expect("Unable to write data"); }
Summary
Congratulations on reading to the end of this tutorial! We have gone through how to read and write to a file for Rust 1.0 and Rust 1.26+.
For further reading on Rust, go to the articles:
- How to Do Bubble Sort in Rust
- How to Concatenate Strings in Rust
- How to Convert String to Integer and Float in Rust
- Howt to Split a String in Rust
Have fun and happy researching!
Suf is a senior advisor in data science with deep expertise in Natural Language Processing, Complex Networks, and Anomaly Detection. Formerly a postdoctoral research fellow, he applied advanced physics techniques to tackle real-world, data-heavy industry challenges. Before that, he was a particle physicist at the ATLAS Experiment of the Large Hadron Collider. Now, he’s focused on bringing more fun and curiosity to the world of science and research online.