pub struct BufReader<R> { /* private fields */ }
Expand description
BufReader<R>
结构体将缓冲添加到任何 reader。
直接使用 Read
实例可能会非常低效。
例如,对 TcpStream
上 read
的每次调用都会导致系统调用。
BufReader<R>
对底层 Read
进行大批量的不频繁读取,并维护结果的内存缓冲区。
BufReader<R>
可以提高对同一文件或网络套接字进行小规模重复读取调用的程序的速度。
一次读取非常多的内容,或者仅读取一次或几次,则无济于事。
从已经在内存中的源读取时,它也没有任何优势,例如 Vec<u8>
.
当 BufReader<R>
被丢弃时,其缓冲区的内容将被丢弃。
在同一流上创建 BufReader<R>
的多个实例可能会导致数据丢失。
将 BufReader<R>
与 BufReader::into_inner
展开包装后,从底层 reader 进行读取也会导致数据丢失。
Examples
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(())
}
RunImplementations§
source§impl<R> BufReader<R>
impl<R> BufReader<R>
1.37.0 · sourcepub fn buffer(&self) -> &[u8] ⓘ
pub fn buffer(&self) -> &[u8] ⓘ
返回对内部缓冲数据的引用。
与 fill_buf
不同,如果缓冲区为空,它将不会尝试填充缓冲区。
Examples
use std::io::{BufReader, BufRead};
use std::fs::File;
fn main() -> std::io::Result<()> {
let f = File::open("log.txt")?;
let mut reader = BufReader::new(f);
assert!(reader.buffer().is_empty());
if reader.fill_buf()?.len() > 0 {
assert!(!reader.buffer().is_empty());
}
Ok(())
}
Runsourcepub fn into_inner(self) -> R
pub fn into_inner(self) -> R
Trait Implementations§
source§impl<R: Read> BufRead for BufReader<R>
impl<R: Read> BufRead for BufReader<R>
source§fn fill_buf(&mut self) -> Result<&[u8]>
fn fill_buf(&mut self) -> Result<&[u8]>
source§fn has_data_left(&mut self) -> Result<bool>
fn has_data_left(&mut self) -> Result<bool>
buf_read_has_data_left
#86423)Read
是否有任何数据可供读取。 Read moresource§impl<R: Read> Read for BufReader<R>
impl<R: Read> Read for BufReader<R>
source§fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<()>
fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<()>
read_buf
#78485)source§fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>
read
相似,不同之处在于它读入缓冲区的一部分。 Read moresource§fn is_read_vectored(&self) -> bool
fn is_read_vectored(&self) -> bool
can_vector
#69941)source§fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize>
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize>
buf
。 Read moresource§fn read_to_string(&mut self, buf: &mut String) -> Result<usize>
fn read_to_string(&mut self, buf: &mut String) -> Result<usize>
buf
。 Read moresource§fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()>
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<()>
read_buf
#78485)cursor
所需的确切字节数。 Read moresource§fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
fn by_ref(&mut self) -> &mut Selfwhere Self: Sized,
Read
实例创建一个 “by reference” 适配器。 Read moresource§impl<R: Seek> Seek for BufReader<R>
impl<R: Seek> Seek for BufReader<R>
source§fn seek(&mut self, pos: SeekFrom) -> Result<u64>
fn seek(&mut self, pos: SeekFrom) -> Result<u64>
在底层 reader 中查找偏移量 (以字节为单位)。
用于使用 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
时相同的位置。
source§fn stream_position(&mut self) -> Result<u64>
fn stream_position(&mut self) -> Result<u64>
从流的开头返回当前查找位置。
返回的值等效于 self.seek(SeekFrom::Current(0))
,但不刷新内部缓冲区。
由于进行了这种优化,该函数不能保证在此之后立即调用 .into_inner()
将在同一位置产生底层 reader。
如果需要该保证,请改用 BufReader::seek
。
Panics
如果内部 reader 的位置小于缓冲数据量,则此函数将为 panic。
如果内部 reader 的 Seek::stream_position
实现不正确,或者由于直接在底层 reader 上调用 Seek::seek
而导致位置不同步,则可能发生这种情况。
Example
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(())
}
Run