Standard Input and Output

BufWriter

std::io::BufWriter<W> is a buffered output wrapper around any type W: Write (such as std::fs::File, std::net::TcpStream, or StdoutLock). It accumulates small writes inside an in-memory buffer (8 KiB = 8,192 bytes by default) and flushes them to the underlying writer W in large contiguous blocks, avoiding the overhead of issuing an OS write system call for every small field or line.

BufWriter<W> vs. LineWriter<W>

Wrapper Type Flush Trigger Best Use Case
BufWriter<W> Only when the 8 KiB buffer fills up, .flush() / .into_inner() is called, or BufWriter is dropped Bulk file generation (CSV, JSON, logs), binary network framing, batch StdoutLock output
LineWriter<W> Whenever a newline byte \n is written (or when the buffer fills up) Interactive terminal output (used internally by std::io::Stdout)
Writing 1,000 Short Lines to a `File`:

  Unbuffered `File`:
    1,000 `writeln!(file, ...)` calls ---> 1,000–2,000 OS `write()` syscalls!

  Buffered `BufWriter<File>`:
    1,000 `writeln!(buf_writer, ...)` ---> Appended in user-space RAM (`Vec<u8>`),
                                           flushed in ~2–3 OS `write()` syscalls!

Key Constructors and Methods on BufWriter<W>

Method Signature Behavior
BufWriter::new(inner) pub fn new(inner: W) -> BufWriter<W> Creates a BufWriter with default 8,192-byte buffer capacity
BufWriter::with_capacity(cap, inner) pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W> Creates a BufWriter with custom byte capacity
.flush(&mut self) fn flush(&mut self) -> Result<()> Writes all buffered bytes to inner and flushes inner
.into_inner(self) pub fn into_inner(self) -> Result<W, IntoInnerError<BufWriter<W>>> Flushes the buffer and returns the unwrapped W (or returns both the error and the BufWriter on failure!)
.buffer(&self) pub fn buffer(&self) -> &[u8] Returns the slice of bytes currently waiting in the buffer
.capacity(&self) pub fn capacity(&self) -> usize Returns the total byte capacity of the internal buffer

Always Call .flush() or .into_inner() Before Dropping a BufWriter

Although BufWriter's Drop implementation attempts to flush any remaining buffered bytes when the BufWriter goes out of scope, Drop::drop cannot return an io::Result—so any disk-full or broken-connection error during automatic drop is silently ignored. Calling writer.flush()? (or let inner = writer.into_inner()?;) before the scope ends surfaces any final write error via Result:

use std::io::{self, BufWriter, Write};

fn main() -> io::Result<()> {
    let mut backing_vec: Vec<u8> = Vec::new();

    {
        let mut writer = BufWriter::with_capacity(64, &mut backing_vec);
        write!(writer, "header:")?;
        write!(writer, "payload")?;

        println!(
            "before flush -> bytes in BufWriter RAM: {} B",
            writer.buffer().len()
        );

        // Explicitly flush and check for errors before `writer` drops:
        writer.flush()?;
        println!(
            "after flush  -> bytes in BufWriter RAM: {} B",
            writer.buffer().len()
        );
    }

    println!(
        "written to backing_vec: {:?}",
        std::str::from_utf8(&backing_vec).unwrap()
    );
    Ok(())
}
before flush -> bytes in BufWriter RAM: 14 B
after flush  -> bytes in BufWriter RAM: 0 B
written to backing_vec: "header:payload"