Reading and writing using the new Rust IO library

March 3, 2015

When the re-write of the std::io module landed in Rust 1.0.0-alpha.2, there were a lot of changes to the way you read/write to a file. I’ll cover some simple examples and probably make edits in the future to add more fancy stuff.

Disclaimer: At the time of writing this, std::io is still a work in progress! I’m also currently learning this new library as I go along, so there may be errors on my behalf as well!

Reading from a file

Reading to a file can be done in two ways (both really simple). I’ll talk about one way here and the second a little later.

let file = match File::open("test_file.txt") {
	Ok(file) => file,
	Err(..)  => panic!("room"),

File::open by default gives you Read permissons, so you can create a BufReader from that.

let mut reader = BufReader::new(&file);

// read_line takes reads a line and writes to a string, so we give it one.
let buffer_string = &mut String::new();
println!("We read a new line: {}", buffer_string);

Writing to a file


A simple example for writing to a file is to start by creating your Path, and an OpenOptions. An OpenOptions is how you provide the file permissons and that you would need to read or write to a file appropriately.

let mut options = OpenOptions::new();
// We want to write to our file as well as append new data to it.

You can also add .read(true) for read permissions as an alternate way to read from the file. Although, the interesting part about OpenOptions is that you can re-use the options set for multiple files:

// We can create a Path
let path = Path::new("test_file.txt");

// or we can also just use a string slice:
let path2 = "test_file2.txt";

// We create file options to write
let mut options = OpenOptions::new();

// Both of these should be valid
let file: Result<File, Error> =;
let file2: Result<File, Error> =;

The actual writing bit

So now that we have the permissons setup correctly, we can create a BufWriter to actually write to the file. I’ve added a match statement to unwrap the unlike the previous snippet:

let file = match {
    Ok(file) => file,
    Err(..) => panic!("at the Disco"),

// We create a buffered writer from the file we get
let mut writer = BufWriter::new(&file);
// Then we write to the file. write_all() calls flush() after the write as well.


In my examples, I’ve used separate buffers but you can use a BufStream as well to get all the same features combined.

Discussion, links, and tweets

I'm a software enginer that's worked on various Android projects for a while now. If you'd like to follow me on Twitter, I don't always post about tech things.