File I-O

Back

Loading concept...

📚 Rust File I/O: Your Computer’s Filing Cabinet

The Big Picture: A Magical Filing Cabinet 🗄️

Imagine your computer has a giant magical filing cabinet. Inside are folders and papers (files) with all kinds of information—photos, stories, game saves, and more!

File I/O (Input/Output) is how your Rust program:

  • Opens the cabinet drawer
  • Reads papers inside (input)
  • Writes new papers or edits old ones (output)
  • Closes the drawer when done

It’s like being a librarian for your computer!


🎯 What You’ll Learn

graph TD A["std::io Module"] --> B["File I/O Basics"] B --> C["Reading Files"] B --> D["Writing Files"] C --> E["BufReader"] D --> F["BufWriter"]

1️⃣ The std::io Module: Your Toolkit

Think of std::io as your librarian’s toolkit. It has everything you need to work with files!

What’s Inside the Toolkit?

Tool What It Does
Read Lets you read stuff
Write Lets you write stuff
BufRead Read smarter, faster
Result Tells you if it worked

Getting Your Toolkit

use std::io;
use std::io::Read;
use std::io::Write;

Simple Example:

use std::io;

fn main() {
    // io gives us tools
    // for reading and writing!
    println!("Toolkit ready!");
}

💡 Remember: std::io is always available. No extra downloads needed!


2️⃣ File I/O: Opening the Cabinet

Before reading or writing, you need to open a file. Think of it like pulling out a specific folder from the cabinet.

Meet std::fs::File

use std::fs::File;

File is your way to grab a specific paper from the cabinet!

Opening a File

use std::fs::File;

fn main() {
    // Try to open a file
    let file = File::open("story.txt");

    match file {
        Ok(f) => println!("Got it!"),
        Err(e) => println!("Oops: {}", e),
    }
}

Why match?

  • The file might not exist! 🤷
  • The match is like asking: “Did we find it or not?”

The Golden Rule

graph TD A["Want to Read?"] -->|Yes| B["File::open"] A -->|No, Write| C["File::create"] B --> D["Opens existing file"] C --> E["Makes new file"]

3️⃣ Reading Files: Getting Information Out

Reading is like looking at a paper in your filing cabinet.

Method 1: Read Everything at Once

use std::fs;

fn main() {
    // Read entire file to string
    let content = fs::read_to_string(
        "hello.txt"
    );

    match content {
        Ok(text) => println!("{}", text),
        Err(e) => println!("Error: {}", e),
    }
}

When to use: Small files, like notes or configs.

Method 2: Read into Bytes

use std::fs::File;
use std::io::Read;

fn main() {
    let mut file = File::open("data.txt")
        .expect("Can't open file");

    let mut buffer = String::new();

    file.read_to_string(&mut buffer)
        .expect("Can't read");

    println!("{}", buffer);
}

Why mut? We’re filling the buffer, so it changes!

The Reading Flow

graph TD A["Open File"] --> B["Create Buffer"] B --> C["Read into Buffer"] C --> D["Use the Data!"] D --> E["File Closes Automatically"]

🎉 Fun Fact: Rust automatically closes files when you’re done. No mess left behind!


4️⃣ Writing Files: Adding New Papers

Writing is like putting a new paper into your cabinet.

Creating a New File

use std::fs::File;
use std::io::Write;

fn main() {
    let mut file = File::create("note.txt")
        .expect("Can't create file");

    file.write_all(b"Hello, Rust!")
        .expect("Can't write");

    println!("Done writing!");
}

What’s that b? It turns text into bytes. Files love bytes!

Appending to a File

Want to add to a file without erasing it?

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

fn main() {
    let mut file = OpenOptions::new()
        .append(true)
        .open("diary.txt")
        .expect("Can't open");

    file.write_all(b"\nNew entry!")
        .expect("Can't write");
}

OpenOptions is like choosing how to open the cabinet:

  • append(true) = add to the end
  • write(true) = allow writing
  • create(true) = make if missing

Writing Cheat Sheet

Goal Method
New file, fresh start File::create()
Add to existing OpenOptions.append(true)
Write if exists OpenOptions.write(true)

5️⃣ BufReader: The Speed Reader 🚀

Imagine reading a book one letter at a time. Slow, right?

BufReader reads in chunks (buffers). Much faster!

Without BufReader (Slow)

// Reads tiny bits, asks disk a lot
// Like asking librarian for
// each letter individually!

With BufReader (Fast!)

use std::fs::File;
use std::io::{BufRead, BufReader};

fn main() {
    let file = File::open("story.txt")
        .expect("Can't open");

    let reader = BufReader::new(file);

    // Read line by line, super fast!
    for line in reader.lines() {
        match line {
            Ok(text) => println!("{}", text),
            Err(_) => break,
        }
    }
}

Why BufReader Rocks

graph LR A["File on Disk"] -->|Small chunks| B["Slow Reading"] A -->|Big buffer| C["BufReader"] C -->|Gives lines| D["Your Program"] D -->|Fast!| E["Happy Coder"]

Reading Lines Made Easy

use std::fs::File;
use std::io::{BufRead, BufReader};

fn main() {
    let file = File::open("list.txt")
        .expect("Oops!");

    let reader = BufReader::new(file);

    for (num, line) in
        reader.lines().enumerate()
    {
        if let Ok(text) = line {
            println!("{}: {}", num+1, text);
        }
    }
}

This prints each line with its number!


6️⃣ BufWriter: The Smart Writer 🖊️

Just like BufReader helps reading, BufWriter makes writing faster!

The Problem

Writing one tiny thing at a time is slow. Your program waits for the disk each time.

The Solution

use std::fs::File;
use std::io::{BufWriter, Write};

fn main() {
    let file = File::create("output.txt")
        .expect("Can't create");

    let mut writer = BufWriter::new(file);

    // Write lots of things fast!
    writer.write_all(b"Line 1\n")
        .expect("Write failed");
    writer.write_all(b"Line 2\n")
        .expect("Write failed");
    writer.write_all(b"Line 3\n")
        .expect("Write failed");

    // Flush to make sure it's saved
    writer.flush()
        .expect("Flush failed");
}

How BufWriter Works

graph TD A["Your writes"] --> B["Buffer fills up"] B --> C{Buffer full?} C -->|Yes| D["Write to disk"] C -->|No| E["Keep buffering"] D --> E E --> F["Flush at end"]

Why Flush Matters

flush() pushes everything from the buffer to the file. Think of it like:

  • Without flush: Writing in invisible ink
  • With flush: Ink becomes permanent!

⚠️ Important: BufWriter flushes automatically when dropped, but calling flush() is good practice!


🎨 Putting It All Together

Here’s a complete example that reads, modifies, and writes:

use std::fs::File;
use std::io::{
    BufRead, BufReader,
    BufWriter, Write
};

fn main() {
    // Read input file
    let input = File::open("input.txt")
        .expect("No input file!");
    let reader = BufReader::new(input);

    // Create output file
    let output = File::create("output.txt")
        .expect("Can't create output!");
    let mut writer = BufWriter::new(output);

    // Copy lines, add numbers
    for (i, line) in
        reader.lines().enumerate()
    {
        if let Ok(text) = line {
            let numbered = format!(
                "{}. {}\n", i+1, text
            );
            writer.write_all(
                numbered.as_bytes()
            ).expect("Write error!");
        }
    }

    writer.flush().expect("Flush error!");
    println!("Done! Check output.txt");
}

🧠 Quick Reference

Task Code
Read whole file fs::read_to_string("f.txt")
Open for reading File::open("f.txt")
Create new file File::create("f.txt")
Fast reading BufReader::new(file)
Fast writing BufWriter::new(file)
Write bytes file.write_all(b"text")
Read lines reader.lines()
Save buffer writer.flush()

🌟 Key Takeaways

  1. std::io is your toolkit for all input/output
  2. File::open reads, File::create writes
  3. BufReader makes reading fast (reads in chunks)
  4. BufWriter makes writing fast (writes in chunks)
  5. Always handle errors with match or expect
  6. Files close automatically in Rust!

🚀 You Did It!

You now know how to:

  • ✅ Use the std::io module
  • ✅ Open, read, and write files
  • ✅ Speed up with BufReader and BufWriter

Your Rust programs can now work with files like a pro librarian! 📚✨

Next Step: Try creating a program that reads your favorite quotes from a file and displays them randomly!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.