Trait BufRead
trait BufRead: Read
A BufRead is a type of Reader which has an internal buffer, allowing it
to perform extra ways of reading.
For example, reading line-by-line is inefficient without using a buffer, so
if you want to read by line, you'll need BufRead, which includes a
read_line method as well as a lines iterator.
Examples
A locked standard input implements BufRead:
use std::io;
use std::io::prelude::*;
let stdin = io::stdin();
for line in stdin.lock().lines() {
println!("{}", line?);
}
# std::io::Result::Ok(())
If you have something that implements Read, you can use the [BufReader
type]BufReader to turn it into a BufRead.
For example, File implements Read, but not BufRead.
BufReader to the rescue!
use std::io::{self, BufReader};
use std::io::prelude::*;
use std::fs::File;
fn main() -> io::Result<()> {
let f = File::open("foo.txt")?;
let f = BufReader::new(f);
for line in f.lines() {
let line = line?;
println!("{line}");
}
Ok(())
}
Required Methods
fn fill_buf(self: &mut Self) -> Result<&[u8]>Returns the contents of the internal buffer, filling it with more data, via
Readmethods, if empty.This is a lower-level method and is meant to be used together with
consume, which can be used to mark bytes that should not be returned by subsequent calls toread.Returns an empty buffer when the stream has reached EOF.
Errors
This function will return an I/O error if a
Readmethod was called, but returned an error.Examples
A locked standard input implements
BufRead:use std::io; use std::io::prelude::*; let stdin = io::stdin(); let mut stdin = stdin.lock(); let buffer = stdin.fill_buf()?; // work with buffer println!("{buffer:?}"); // mark the bytes we worked with as read let length = buffer.len(); stdin.consume(length); # std::io::Result::Ok(())fn consume(self: &mut Self, amount: usize)Marks the given
amountof additional bytes from the internal buffer as having been read. Subsequent calls toreadonly return bytes that have not been marked as read.This is a lower-level method and is meant to be used together with
fill_buf, which can be used to fill the internal buffer viaReadmethods.It is a logic error if
amountexceeds the number of unread bytes in the internal buffer, which is returned byfill_buf.Examples
Since
consume()is meant to be used withfill_buf, that method's example includes an example ofconsume().
Provided Methods
fn has_data_left(self: &mut Self) -> Result<bool>Checks if there is any data left to be
read.This function may fill the buffer to check for data, so this function returns
Result<bool>, notbool.The default implementation calls
fill_bufand checks that the returned slice is empty (which means that there is no data left, since EOF is reached).Errors
This function will return an I/O error if a
Readmethod was called, but returned an error.Examples
use io; use *; let stdin = stdin; let mut stdin = stdin.lock; while stdin.has_data_left? # Okfn read_until(self: &mut Self, byte: u8, buf: &mut Vec<u8>) -> Result<usize>Reads all bytes into
bufuntil the delimiterbyteor EOF is reached.This function will read bytes from the underlying stream until the delimiter or EOF is found. Once found, all bytes up to, and including, the delimiter (if found) will be appended to
buf.If successful, this function will return the total number of bytes read.
This function is blocking and should be used carefully: it is possible for an attacker to continuously send bytes without ever sending the delimiter or EOF.
Errors
This function will ignore all instances of
ErrorKind::Interruptedand will otherwise return any errors returned byfill_buf.If an I/O error is encountered then all bytes read so far will be present in
bufand its length will have been adjusted appropriately.Examples
[
std::io::Cursor]Cursoris a type that implementsBufRead. In this example, we useCursorto read all the bytes in a byte slice in hyphen delimited segments:use ; let mut cursor = new; let mut buf = vec!; // cursor is at 'l' let num_bytes = cursor.read_until .expect; assert_eq!; assert_eq!; buf.clear; // cursor is at 'i' let num_bytes = cursor.read_until .expect; assert_eq!; assert_eq!; buf.clear; // cursor is at EOF let num_bytes = cursor.read_until .expect; assert_eq!; assert_eq!;fn skip_until(self: &mut Self, byte: u8) -> Result<usize>Skips all bytes until the delimiter
byteor EOF is reached.This function will read (and discard) bytes from the underlying stream until the delimiter or EOF is found.
If successful, this function will return the total number of bytes read, including the delimiter byte if found.
This is useful for efficiently skipping data such as NUL-terminated strings in binary file formats without buffering.
This function is blocking and should be used carefully: it is possible for an attacker to continuously send bytes without ever sending the delimiter or EOF.
Errors
This function will ignore all instances of
ErrorKind::Interruptedand will otherwise return any errors returned byfill_buf.If an I/O error is encountered then all bytes read so far will be present in
bufand its length will have been adjusted appropriately.Examples
[
std::io::Cursor]Cursoris a type that implementsBufRead. In this example, we useCursorto read some NUL-terminated information about Ferris from a binary string, skipping the fun fact:use ; let mut cursor = new; // read name let mut name = Vecnew; let num_bytes = cursor.read_until .expect; assert_eq!; assert_eq!; // skip fun fact let num_bytes = cursor.skip_until .expect; assert_eq!; // read animal type let mut animal = Vecnew; let num_bytes = cursor.read_until .expect; assert_eq!; assert_eq!; // reach EOF let num_bytes = cursor.skip_until .expect; assert_eq!;fn read_line(self: &mut Self, buf: &mut String) -> Result<usize>Reads all bytes until a newline (the
0xAbyte) is reached, and append them to the providedStringbuffer.Previous content of the buffer will be preserved. To avoid appending to the buffer, you need to
clearit first.This function will read bytes from the underlying stream until the newline delimiter (the
0xAbyte) or EOF is found. Once found, all bytes up to, and including, the delimiter (if found) will be appended tobuf.If successful, this function will return the total number of bytes read.
If this function returns
Ok(0), the stream has reached EOF.This function is blocking and should be used carefully: it is possible for an attacker to continuously send bytes without ever sending a newline or EOF. You can use
taketo limit the maximum number of bytes read.Errors
This function has the same error semantics as
read_untiland will also return an error if the read bytes are not valid UTF-8. If an I/O error is encountered thenbufmay contain some bytes already read in the event that all data read so far was valid UTF-8.Examples
[
std::io::Cursor]Cursoris a type that implementsBufRead. In this example, we useCursorto read all the lines in a byte slice:use ; let mut cursor = new; let mut buf = Stringnew; // cursor is at 'f' let num_bytes = cursor.read_line .expect; assert_eq!; assert_eq!; buf.clear; // cursor is at 'b' let num_bytes = cursor.read_line .expect; assert_eq!; assert_eq!; buf.clear; // cursor is at EOF let num_bytes = cursor.read_line .expect; assert_eq!; assert_eq!;fn split(self: Self, byte: u8) -> Split<Self> where Self: SizedReturns an iterator over the contents of this reader split on the byte
byte.The iterator returned from this function will return instances of
io::Result<[Vec]<u8>>. Each vector returned will not have the delimiter byte at the end.This function will yield errors whenever
read_untilwould have also yielded an error.Examples
[
std::io::Cursor]Cursoris a type that implementsBufRead. In this example, we useCursorto iterate over all hyphen delimited segments in a byte sliceuse ; let cursor = new; let mut split_iter = cursor.split.map; assert_eq!; assert_eq!; assert_eq!; assert_eq!;fn lines(self: Self) -> Lines<Self> where Self: SizedReturns an iterator over the lines of this reader.
The iterator returned from this function will yield instances of
io::Result<[String]>. Each string returned will not have a newline byte (the0xAbyte) orCRLF(0xD,0xAbytes) at the end.Examples
[
std::io::Cursor]Cursoris a type that implementsBufRead. In this example, we useCursorto iterate over all the lines in a byte slice.use ; let cursor = new; let mut lines_iter = cursor.lines.map; assert_eq!; assert_eq!; assert_eq!; assert_eq!;Errors
Each line of the iterator has the same error semantics as
BufRead::read_line.
Implementors
impl BufRead for StdinLock<'_>impl<T> BufRead for Cursor<T>impl<A: Allocator> BufRead for crate::collections::VecDeque<u8, A>impl BufRead for Emptyimpl<B: BufRead + ?Sized> BufRead for &mut Bimpl BufRead for &[u8]impl<T: BufRead> BufRead for Take<T>impl<R: ?Sized + Read> BufRead for BufReader<R>impl<B: BufRead + ?Sized> BufRead for Box<B>impl<T: BufRead, U: BufRead> BufRead for Chain<T, U>