Struct std::io::BufReader
pub struct BufReader<R> { /* private fields */ }BufReader<R> 结构体将缓冲添加到任何 reader。
直接使用 Read 实例可能会非常低效。 例如,对 TcpStream 上 read 的每次调用都会导致系统调用。 BufReader<R> 对底层 Read 进行大批量的不频繁读取,并维护结果的内存缓冲区。
BufReader<R> 可以提高对同一文件或网络套接字进行小规模重复读取调用的程序的速度。
一次读取非常多的内容,或者仅读取一次或几次,则无济于事。 从已经在内存中的源读取时,它也没有任何优势,例如 Vec<u8>。
当 BufReader<R> 被丢弃时,其缓冲区的内容将被丢弃。 在同一流上创建 BufReader<R> 的多个实例可能会导致数据丢失。 将 BufReader<R> 与 BufReader::into_inner 展开包装后,从底层 reader 进行读取也会导致数据丢失。
简而言之就是BufReader可以简化读取,从一个字节一个字节读取,变成一次读取一大块
示例
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 中进行更改。
pub fn new(inner: R) -> BufReader<R>参数:
- inner:一个
Read,从这个reader中创建BufReader
返回值:返回一个具有默认缓冲区容量的新 BufReader
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>。
pub fn with_capacity(capacity: usize, inner: R) -> BufReader<R>参数:
- capacity:指定缓冲区的容量
- inner:一个
Read,从这个reader中创建BufReader
返回值:返回一个具有默认缓冲区容量的新 BufReader
impl<R> BufReader<R>
get_ref
获取对底层 reader 的引用。
直接从底层 reader 读取是不可取的。
pub fn get_ref(&self) -> &R返回值:返回一个reader的引用
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 读取是不可取的。
pub fn get_mut(&mut self) -> &mut R返回值:返回一个reader的可变引用
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 不同,如果缓冲区为空,它将不会尝试填充缓冲区。
pub fn buffer(&self) -> &[u8]返回值:返回reader内部的缓冲数据,字节形式
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
返回内部缓冲区可以一次保存的字节数。
pub fn capacity(&self) -> usize返回值:返回内部缓冲区可以一次保存的字节数,默认为8kb
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 进行后续读取可能会导致数据丢失。
pub fn into_inner(self) -> R返回值:返回BufReader内部的reader
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 的位置,因此如果需要,调用者必须自己跟踪此信息。
pub fn seek_relative(&mut self, offset: i64) -> Result<()>参数:
- offset:相对于当前位置的寻找的偏移量,注意此参数是i64,
- 正数:向后移动
- 负数:向前移动
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 中的更多数据填充内部缓冲区。
fn fill_buf(&mut self) -> Result<&[u8]>consume
告诉此缓冲区 amt 字节已从缓冲区中消耗掉,因此在调用 read 时不再应返回它们。
fn consume(&mut self, amt: usize)has_data_left
检查底层 Read 是否有任何数据可供读取。
fn has_data_left(&mut self) -> Result<bool>read_until
将所有字节读入 buf,直到到达定界符 byte 或 EOF。
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize>read_line
读取所有字节直到到达换行符 (0xA 字节),并将它们,追加,到提供的 String 缓冲区。
fn read_line(&mut self, buf: &mut String) -> Result<usize>split
返回对该字节 byte 上的 reader 拆分内容的迭代器。
fn split(self, byte: u8) -> Split<Self>
where
Self: Sized,lines
返回此 reader 的各行上的迭代器。
fn lines(self) -> Lines<Self>
where
Self: Sized,impl<R> Debug for BufReader<R>
impl<R> Debug for BufReader<R>
where
R: Debug,fmt
使用给定的格式化程序格式化该值。
fn fmt(&self, fmt: &mut Formatter<'_>) -> Resultimpl<R: Read> Read for BufReader<R>
read
从该源中提取一些字节到指定的缓冲区中,返回读取的字节数。
fn read(&mut self, buf: &mut [u8]) -> Result<usize>read_buf
从此源中提取一些字节到指定的缓冲区中
fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<()>read_exact
读取填充 buf 所需的确切字节数。
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()>read_vectored
与 read 相似,不同之处在于它读入缓冲区的一部分。
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>is_read_vectored
确定此 Read 是否具有有效的 read_vectored 实现。
fn is_read_vectored(&self) -> boolread_to_end
读取所有字节,直到此源中的 EOF 为止,然后将它们放入 buf。
fn (&mut self, buf: &mut Vec<u8>) -> Result<usize>read_to_string
读取这个源中的所有字节,直到 EOF 为止,然后将它们追加到 buf。
fn read_to_string(&mut self, buf: &mut String) -> Result<usize>read_buf_exact
读取填充 cursor 所需的确切字节数。
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()>by_ref
为这个 Read 实例创建一个 “by reference” 适配器。
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,bytes
将此 Read 实例的字节数转换为 Iterator。
fn bytes(self) -> Bytes<Self> ⓘ
where
Self: Sized,chain
创建一个适配器,将这个流与另一个链接起来。
fn chain<R: Read>(self, next: R) -> Chain<Self, R> ⓘ
where
Self: Sized,take
创建一个适配器,最多从中读取 limit 个字节。
fn take(self, limit: u64) -> Take<Self> ⓘ
where
Self: Sized,impl<R: Seek> Seek for BufReader<R>
seek
在底层 reader 中查找偏移量 (以字节为单位)。
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
从流的开头返回当前查找位置。
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 而导致位置不同步,则可能发生这种情况。
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
返回到流的开头。
fn rewind(&mut self) -> Result<()>stream_len
返回此流的长度 (以字节为单位)。
fn stream_len(&mut self) -> Result<u64>Auto Trait Implementations
impl<R> RefUnwindSafe for BufReader<R>
impl<R> RefUnwindSafe for BufReader<R>
where
R: RefUnwindSafe,impl<R> Send for BufReader<R>
impl<R> Send for BufReader<R>
where
R: Send,impl<R> Sync for BufReader<R>
impl<R> Sync for BufReader<R>
where
R: Sync,impl<R> Unpin for BufReader<R>
impl<R> Unpin for BufReader<R>
where
R: Unpin,impl<R> UnwindSafe for BufReader<R>
impl<R> UnwindSafe for BufReader<R>
where
R: UnwindSafe,Blanket Implementations
impl<T> Any for T
impl<T> Any for T
where
T: 'static + ?Sized,impl<T> Borrow<T> for T
impl<T> Borrow<T> for T
where
T: ?Sized,impl<T> BorrowMut<T> for T
impl<T> BorrowMut<T> for T
where
T: ?Sized,impl<T> From<T> for T
impl<T> From<T> for Timpl<T, U> Into<U> for T
impl<T, U> Into<U> for T
where
U: From<T>,impl<T, U> TryFrom<U> for T
impl<T, U> TryFrom<U> for T
where
U: Into<T>,impl<T, U> TryInto<U> for T
impl<T, U> TryInto<U> for T
where
U: TryFrom<T>,