Skip to content

Struct std::io::BufReader

rust
pub struct BufReader<R> { /* private fields */ }

BufReader<R> 结构体将缓冲添加到任何 reader。

直接使用 Read 实例可能会非常低效。 例如,对 TcpStreamread 的每次调用都会导致系统调用。 BufReader<R> 对底层 Read 进行大批量的不频繁读取,并维护结果的内存缓冲区。

BufReader<R> 可以提高对同一文件或网络套接字进行小规模重复读取调用的程序的速度。

一次读取非常多的内容,或者仅读取一次或几次,则无济于事。 从已经在内存中的源读取时,它也没有任何优势,例如 Vec<u8>

BufReader<R> 被丢弃时,其缓冲区的内容将被丢弃。 在同一流上创建 BufReader<R> 的多个实例可能会导致数据丢失。 将 BufReader<R>BufReader::into_inner 展开包装后,从底层 reader 进行读取也会导致数据丢失。

简而言之就是BufReader可以简化读取,从一个字节一个字节读取,变成一次读取一大块

示例

rust
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::File;

fn main() -> std::io::Result<()> {
    let f = File::open("log.txt")?;
    let mut reader = BufReader::new(f);

    let mut line = String::new();
    let len = reader.read_line(&mut line)?;
    println!("First line is {len} bytes long");
    Ok(())
}

Implementations

impl<R: Read> BufReader<R>

new

创建一个具有默认缓冲区容量的新 BufReader<R>。 当前默认值为 8 KB,但可能会在 future 中进行更改。

rust
pub fn new(inner: R) -> BufReader<R>

参数

  • inner:一个Read,从这个reader中创建BufReader

返回值:返回一个具有默认缓冲区容量的新 BufReader

rust
use std::io::BufReader;
use std::fs::File;

fn main() -> std::io::Result<()> {
    let f = File::open("log.txt")?;
    let reader = BufReader::new(f);
    Ok(())
}

with_capacity

用指定的缓冲区容量创建一个新的 BufReader<R>

rust
pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R>

参数

  • capacity:指定缓冲区的容量
  • inner:一个Read,从这个reader中创建BufReader

返回值:返回一个具有默认缓冲区容量的新 BufReader

impl<R> BufReader<R>

get_ref

获取对底层 reader 的引用。

直接从底层 reader 读取是不可取的。

rust
pub fn get_ref(&self) -> &R

返回值:返回一个reader的引用

rust
use std::io::BufReader;
use std::fs::File;

fn main() -> std::io::Result<()> {
    let f1 = File::open("log.txt")?;
    let reader = BufReader::new(f1);

    let f2 = reader.get_ref();
    Ok(())
}

get_mut

获取底层 reader 的可变引用。

直接从底层 reader 读取是不可取的。

rust
pub fn get_mut(&mut self) -> &mut R

返回值:返回一个reader的可变引用

rust
use std::io::BufReader;
use std::fs::File;

fn main() -> std::io::Result<()> {
    let f1 = File::open("log.txt")?;
    let mut reader = BufReader::new(f1);

    let f2 = reader.get_mut();
    Ok(())
}

buffer

返回对内部缓冲数据的引用。

fill_buf 不同,如果缓冲区为空,它将不会尝试填充缓冲区。

rust
pub fn buffer(&self) -> &[u8]

返回值:返回reader内部的缓冲数据,字节形式

rust
use std::{fs::File, io::BufReader, io::Read};

fn main() {
    let file = File::open("test.txt").unwrap();
    let mut reader = BufReader::new(file);

    let mut buf = [0u8; 8];
    reader.read(&mut buf).unwrap();

    let buffer = reader.buffer();

    println!("{:#?}", buffer)   
	/*
		[
			50,
			49,
			51,
			50,
			49,
			50,
		]
	 */
}

capacity

返回内部缓冲区可以一次保存的字节数。

rust
pub fn capacity(&self) -> usize

返回值:返回内部缓冲区可以一次保存的字节数,默认为8kb

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

fn main() {
    let file = File::open("test.txt").unwrap();
    let reader = BufReader::new(file);

    let capacity = reader.capacity();

    println!("{:#?}", capacity)   // 8192   也就是8kb
}

into_inner

解包此 BufReader<R>,返回底层 reader。

请注意,内部缓冲区中的所有剩余数据都会丢失。 因此,从底层 reader 进行后续读取可能会导致数据丢失。

rust
pub fn into_inner(self) -> R

返回值:返回BufReader内部的reader

rust
use std::io::BufReader;
use std::fs::File;

fn main() -> std::io::Result<()> {
    let f1 = File::open("log.txt")?;
    let reader = BufReader::new(f1);

    let f2 = reader.into_inner();
    Ok(())
}

impl<R: Seek> BufReader<R>

seek_relative

相对于当前位置移动文件指针。 如果新位置位于缓冲区内,则不会刷新缓冲区,从而实现更有效的查找。 此方法不返回底层 reader 的位置,因此如果需要,调用者必须自己跟踪此信息。

rust
pub fn seek_relative(&mut self, offset: i64) -> Result<()>

参数

  • offset:相对于当前位置的寻找的偏移量,注意此参数是i64,
    • 正数:向后移动
    • 负数:向前移动
rust
use std::fs::File;
use std::io::{self, BufReader, Seek, SeekFrom};

fn main() -> io::Result<()> {
    let file = File::open("test.txt")?;
    let mut reader = BufReader::new(file);

    // 跳过前 5 个字节
    reader.seek_relative(5)?;

    // 再往回退 2 个字节
    reader.seek_relative(-2)?;

    Ok(())
}

Trait Implementations

impl<R: Read> BufRead for BufReader<R>

fill_buf

返回内部缓冲区的内容,如果内部缓冲区为空,则使用内部 reader 中的更多数据填充内部缓冲区。

rust
fn fill_buf(&mut self) -> Result<&[u8]>

consume

告诉此缓冲区 amt 字节已从缓冲区中消耗掉,因此在调用 read 时不再应返回它们。

rust
fn consume(&mut self, amt: usize)

has_data_left

检查底层 Read 是否有任何数据可供读取。

rust
fn has_data_left(&mut self) -> Result<bool>

read_until

将所有字节读入 buf,直到到达定界符 byte 或 EOF。

rust
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize>

read_line

读取所有字节直到到达换行符 (0xA 字节),并将它们,追加,到提供的 String 缓冲区。

rust
fn read_line(&mut self, buf: &mut String) -> Result<usize>

split

返回对该字节 byte 上的 reader 拆分内容的迭代器。

rust
fn split(self, byte: u8) -> Split<Self> 
where
  Self: Sized,

lines

返回此 reader 的各行上的迭代器。

rust
fn lines(self) -> Lines<Self>
where
  Self: Sized,

impl<R> Debug for BufReader<R>

rust
impl<R> Debug for BufReader<R>
where
  R: Debug,

fmt

使用给定的格式化程序格式化该值。

rust
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result

impl<R: Read> Read for BufReader<R>

read

从该源中提取一些字节到指定的缓冲区中,返回读取的字节数。

rust
fn read(&mut self, buf: &mut [u8]) -> Result<usize>

read_buf

从此源中提取一些字节到指定的缓冲区中

rust
fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<()>

read_exact

读取填充 buf 所需的确切字节数。

rust
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()>

read_vectored

与 read 相似,不同之处在于它读入缓冲区的一部分。

rust
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>

is_read_vectored

确定此 Read 是否具有有效的 read_vectored 实现。

rust
fn is_read_vectored(&self) -> bool

read_to_end

读取所有字节,直到此源中的 EOF 为止,然后将它们放入 buf。

rust
fn (&mut self, buf: &mut Vec<u8>) -> Result<usize>

read_to_string

读取这个源中的所有字节,直到 EOF 为止,然后将它们追加到 buf。

rust
fn read_to_string(&mut self, buf: &mut String) -> Result<usize>

read_buf_exact

读取填充 cursor 所需的确切字节数。

rust
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()>

by_ref

为这个 Read 实例创建一个 “by reference” 适配器。

rust
fn by_ref(&mut self) -> &mut Self
where
  Self: Sized,

bytes

将此 Read 实例的字节数转换为 Iterator。

rust
fn bytes(self) -> Bytes<Self> ⓘ
where
  Self: Sized,

chain

创建一个适配器,将这个流与另一个链接起来。

rust
fn chain<R: Read>(self, next: R) -> Chain<Self, R> ⓘ
where
  Self: Sized,

take

创建一个适配器,最多从中读取 limit 个字节。

rust
fn take(self, limit: u64) -> Take<Self> ⓘ
where
  Self: Sized,

impl<R: Seek> Seek for BufReader<R>

seek

在底层 reader 中查找偏移量 (以字节为单位)。

rust
fn seek(&mut self, pos: SeekFrom) -> Result<u64>

用于使用 SeekFrom::Current(_) 查找的位置是底层 reader 所在的位置,如果 BufReader<R> 没有内部缓冲区。

查找总是会丢弃内部缓冲区,即使查找位置本来会落在内部缓冲区内。 这保证了在查找之后立即调用 BufReader::into_inner() 会在相同位置产生底层 reader。

要在不丢弃内部缓冲区的情况下进行查找,请使用 BufReader::seek_relative。

有关更多详细信息,请参见 std::io::Seek。

Note: 在 edge 情况下,您使用 SeekFrom::Current(n) 进行查找,其中 n 减去内部缓冲区长度会溢出 i64,将执行两次查找而不是一次查找。

如果第二个 seek 返回 Err,则底层 reader 将保留在与使用 SeekFrom::Current(0) 调用 seek 时相同的位置。

stream_position

从流的开头返回当前查找位置。

rust
fn stream_position(&mut self) -> Result<u64>

返回的值等效于 self.seek(SeekFrom::Current(0)),但不刷新内部缓冲区。 由于进行了这种优化,该函数不能保证在此之后立即调用 .into_inner() 将在同一位置产生底层 reader。 如果需要该保证,请改用 BufReader::seek

TIP

Panics

如果内部 reader 的位置小于缓冲数据量,则此函数将为 panic。 如果内部 reader 的 Seek::stream_position 实现不正确,或者由于直接在底层 reader 上调用 Seek::seek 而导致位置不同步,则可能发生这种情况。

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


fn main() -> io::Result<()> {

  let mut f = BufReader::new(File::open("foo.txt")?);


  let before = f.stream_position()?;
  f.read_line(&mut String::new())?;
  let after = f.stream_position()?;


  println!("The first line was {} bytes long", after - before);
  Ok(())
}

rewind

返回到流的开头。

rust
fn rewind(&mut self) -> Result<()>

stream_len

返回此流的长度 (以字节为单位)。

rust
fn stream_len(&mut self) -> Result<u64>

Auto Trait Implementations

impl<R> RefUnwindSafe for BufReader<R>

rust
impl<R> RefUnwindSafe for BufReader<R>
where
  R: RefUnwindSafe,

impl<R> Send for BufReader<R>

rust
impl<R> Send for BufReader<R>
where
  R: Send,

impl<R> Sync for BufReader<R>

rust
impl<R> Sync for BufReader<R>
where
  R: Sync,

impl<R> Unpin for BufReader<R>

rust
impl<R> Unpin for BufReader<R>
where
  R: Unpin,

impl<R> UnwindSafe for BufReader<R>

rust
impl<R> UnwindSafe for BufReader<R>
where
  R: UnwindSafe,

Blanket Implementations

impl<T> Any for T

rust
impl<T> Any for T
where
  T: 'static + ?Sized,

impl<T> Borrow<T> for T

rust
impl<T> Borrow<T> for T
where
  T: ?Sized,

impl<T> BorrowMut<T> for T

rust
impl<T> BorrowMut<T> for T
where
  T: ?Sized,

impl<T> From<T> for T

rust
impl<T> From<T> for T

impl<T, U> Into<U> for T

rust
impl<T, U> Into<U> for T
where
  U: From<T>,

impl<T, U> TryFrom<U> for T

rust
impl<T, U> TryFrom<U> for T
where
  U: Into<T>,

impl<T, U> TryInto<U> for T

rust
impl<T, U> TryInto<U> for T
where
  U: TryFrom<T>,

MIT Licensed