File::open() / File::create()
To read from and write to files in Rust using file handles, open a file with File::open() or File::create(), then use BufReader or BufWriter to process data line by line with buffering.
Syntax
use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Write};
// Open a file for reading.
let file = File::open("input.txt")?;
let reader = BufReader::new(file);
// Read line by line.
for line in reader.lines() {
let line = line?;
println!("{}", line);
}
// Create a file for writing (overwrites existing content).
let file = File::create("output.txt")?;
let mut writer = BufWriter::new(file);
writeln!(writer, "Hello, Rust!")?;
writer.flush()?;
// Open a file in append mode.
use std::fs::OpenOptions;
let file = OpenOptions::new().append(true).open("log.txt")?;
Types and Methods
| Type / Method | Description |
|---|---|
| File::open(path) | Opens a file in read-only mode. Returns Result<File>. |
| File::create(path) | Creates a file for writing (overwrites any existing file). Returns Result<File>. |
| BufReader::new(file) | Wraps a file with buffering to improve read performance. |
| BufWriter::new(file) | Wraps a file with buffering to improve write performance. |
| reader.lines() | Returns a line-by-line iterator (newline characters are stripped). |
| reader.read_line(&mut s) | Reads one line into a string. Returns the number of bytes read. |
| writeln!(writer, ...) | Writes to the buffer with a trailing newline. |
| writer.flush() | Flushes the buffer, writing all buffered data to the file. |
| OpenOptions::new() | Specifies fine-grained open modes (read / write / append / create / truncate). |
Sample Code
use std::fs::{self, File, OpenOptions};
use std::io::{self, BufRead, BufReader, BufWriter, Write};
fn main() -> io::Result<()> {
// Create a test file.
fs::write("sample.txt", "Apple\nBanana\nCherry\nDate\n")?;
// --- Read line by line with BufReader ---
let file = File::open("sample.txt")?;
let reader = BufReader::new(file);
println!("=== Reading line by line ===");
for (i, line) in reader.lines().enumerate() {
let line = line?;
println!("Line {}: {}", i + 1, line);
}
// --- Write with BufWriter ---
let file = File::create("output.txt")?;
let mut writer = BufWriter::new(file);
writeln!(writer, "Line 1")?;
writeln!(writer, "Line 2")?;
write!(writer, "Line 3 (no newline)")?;
writer.flush()?; // Flush the buffer to disk.
println!("\nWrote to output.txt");
// --- Append mode with OpenOptions ---
let file = OpenOptions::new()
.append(true) // Append mode
.open("output.txt")?;
let mut writer = BufWriter::new(file);
writeln!(writer, "\nLine 4 (appended)")?;
writer.flush()?;
println!("Appended to file");
// --- Read one line at a time with read_line ---
let file = File::open("output.txt")?;
let mut reader = BufReader::new(file);
let mut line = String::new();
let bytes = reader.read_line(&mut line)?;
println!("\nFirst line: {:?} ({} bytes)", line.trim(), bytes);
// Clean up
fs::remove_file("sample.txt")?;
fs::remove_file("output.txt")?;
Ok(())
}
Notes
When processing large files, wrapping the file in a BufReader reduces the number of I/O calls and improves performance. For line-by-line processing, the reader.lines() iterator is the most convenient approach.
Always call writer.flush() after writing to ensure buffered data is written to the file. While BufWriter flushes automatically when it goes out of scope, any errors during that implicit flush are silently ignored, so flushing explicitly is recommended.
For simpler whole-file reads and writes, see std::fs::read_to_string() / write(). For standard I/O, see std::io::stdin() / stdout().
If you find any errors or copyright issues, please contact us.