Standard Input and Output
BufReader
std::io::BufReader<R> is a generic struct that wraps any type R: Read (such as std::fs::File or std::net::TcpStream), adding an internal heap-allocated byte buffer (8 KiB = 8,192 bytes by default) and implementing both Read and BufRead.
Key Constructors and Methods on BufReader<R>
| Method | Signature | Behavior |
|---|---|---|
BufReader::new(inner) |
pub fn new(inner: R) -> BufReader<R> |
Wraps inner with the default 8,192-byte buffer capacity |
BufReader::with_capacity(cap, inner) |
pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R> |
Wraps inner with a custom buffer size (e.g., 64 * 1024 for large sequential file scans) |
.get_ref(&self) |
pub fn get_ref(&self) -> &R |
Borrows the underlying reader R |
.get_mut(&mut self) |
pub fn get_mut(&mut self) -> &mut R |
Mutably borrows the underlying reader R |
.buffer(&self) |
pub fn buffer(&self) -> &[u8] |
Returns the slice of bytes currently buffered in memory and not yet consumed |
.capacity(&self) |
pub fn capacity(&self) -> usize |
Returns the total allocated byte capacity of the internal buffer |
.into_inner(self) |
pub fn into_inner(self) -> R |
Unwraps and returns R (Warning: discards any unread bytes currently sitting in .buffer()!) |
.seek_relative(offset) |
pub fn seek_relative(&mut self, offset: i64) -> Result<()> (where R: Seek) |
Seeks within the existing memory buffer if offset lands inside .buffer(), avoiding an OS lseek syscall! |
Reading a File Line by Line with BufReader::new(file)
use std::fs::{self, File};
use std::io::{self, BufRead, BufReader, Write};
fn main() -> io::Result<()> {
let path = std::env::temp_dir().join("rust_ch49_bufreader_demo.txt");
{
let mut f = File::create(&path)?;
writeln!(f, "100")?;
writeln!(f, "250")?;
writeln!(f, "400")?;
}
let file = File::open(&path)?;
// Wrap `File` in `BufReader` (64 KiB custom capacity):
let reader = BufReader::with_capacity(64 * 1024, file);
let mut sum: i64 = 0;
for line in reader.lines() {
let num: i64 = line?.trim().parse().unwrap();
sum += num;
}
fs::remove_file(&path)?;
println!("sum of lines read via BufReader: {}", sum);
Ok(())
}
sum of lines read via BufReader: 750
Caution When Calling .into_inner() or .get_mut() on a BufReader
Because BufReader reads ahead from the underlying R in 8 KiB chunks, the underlying File or TcpStream cursor is usually ahead of the logical BufReader cursor by reader.buffer().len() bytes!
- If you read a header with
BufReaderand then calllet raw_stream = reader.into_inner();, any payload bytes that were already pulled intoreader.buffer()during the header read will be lost! Keep using theBufReader(or readreader.buffer()before calling.into_inner()).