Trait std::io::BufRead

1.0.0 · source ·
pub trait BufRead: Read {
    // Required methods
    fn fill_buf(&mut self) -> Result<&[u8]>;
    fn consume(&mut self, amt: usize);

    // Provided methods
    fn has_data_left(&mut self) -> Result<bool> { ... }
    fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> { ... }
    fn read_line(&mut self, buf: &mut String) -> Result<usize> { ... }
    fn split(self, byte: u8) -> Split<Self> 
       where Self: Sized { ... }
    fn lines(self) -> Lines<Self> 
       where Self: Sized { ... }
}
Expand description

BufRead 是带有内部缓冲区的 Read 类型,它可以执行其他读取方式。

例如,在不使用缓冲区的情况下,逐行读取效率很低,因此,如果要逐行读取,则需要 BufRead,其中包括 read_line 方法和 lines 迭代器。

Examples

锁定的标准输入实现 BufRead

use std::io;
use std::io::prelude::*;

let stdin = io::stdin();
for line in stdin.lock().lines() {
    println!("{}", line.unwrap());
}
Run

如果您具有实现 Read 的功能,则可以使用 BufReader type 将其转换为 BufRead

例如,File 实现 Read,但不实现 BufReadBufReader 来救援!

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() {
        println!("{}", line.unwrap());
    }

    Ok(())
}
Run

Required Methods§

source

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

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

此函数是较低级别的调用。它需要与 consume 方法配对才能正确执行功能。 当调用此方法时,任何内容都不是 “read”,因为稍后调用 read 可能会返回相同的内容。 因此,必须使用此缓冲区消耗的字节数来调用 consume,以确保字节永远不会返回两次。

返回的空缓冲区表示流已达到 EOF。

Errors

如果读取了底层 reader,但返回了错误,则此函数将返回 I/O 错误。

Examples

锁定的标准输入实现 BufRead

use std::io;
use std::io::prelude::*;

let stdin = io::stdin();
let mut stdin = stdin.lock();

let buffer = stdin.fill_buf().unwrap();

// 使用缓冲区
println!("{buffer:?}");

// 确保我们处理过的字节以后不再返回
let length = buffer.len();
stdin.consume(length);
Run
source

fn consume(&mut self, amt: usize)

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

此函数是较低级别的调用。它需要与 fill_buf 方法配合才能正常使用。 该函数不执行任何 I/O,它只是通知对象从 fill_buf 返回的某些缓冲区已被消耗,不应再返回。

因此,如果在调用 fill_buf 之前未对其进行调用,则此函数可能会做一些奇怪的事情。

amt 必须为 <=,即 fill_buf 返回的缓冲区中的字节数。

Examples

由于 consume() 旨在与 fill_buf 一起使用,因此该方法的示例包括 consume() 的示例。

Provided Methods§

source

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

🔬This is a nightly-only experimental API. (buf_read_has_data_left #86423)

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

这个函数可能会填充缓冲区来检查数据,所以这个函数返回的是 Result<bool>,而不是 bool

默认实现调用 fill_buf 并检查返回的 4 为空 (这意味着没有数据剩余,因为达到了 EOF)。

Examples

#![feature(buf_read_has_data_left)]
use std::io;
use std::io::prelude::*;

let stdin = io::stdin();
let mut stdin = stdin.lock();

while stdin.has_data_left().unwrap() {
    let mut line = String::new();
    stdin.read_line(&mut line).unwrap();
    // 与行一起工作
    println!("{line:?}");
}
Run
source

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

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

该函数将从底层流中读取字节,直到找到定界符或 EOF。 一旦找到,直到并包括分隔符 (如果找到) 的所有字节都将被追加到 buf

如果成功,此函数将返回读取的字节总数。

该函数正在阻塞,应谨慎使用:攻击者有可能连续发送字节而无需发送定界符或 EOF。

Errors

该函数将忽略 ErrorKind::Interrupted 的所有实例,否则将返回 fill_buf 返回的任何错误。

如果遇到 I/O 错误,则 buf 中将存在到目前为止已读取的所有字节,并且已对其长度进行了适当的调整。

Examples

std::io::Cursor 是一种实现了 BufRead 的类型。 在此示例中,我们使用 Cursor 读取以连字符分隔的段中的字节片中的所有字节:

use std::io::{self, BufRead};

let mut cursor = io::Cursor::new(b"lorem-ipsum");
let mut buf = vec![];

// 游标在 'l'
let num_bytes = cursor.read_until(b'-', &mut buf)
    .expect("reading from cursor won't fail");
assert_eq!(num_bytes, 6);
assert_eq!(buf, b"lorem-");
buf.clear();

// 游标在 'i'
let num_bytes = cursor.read_until(b'-', &mut buf)
    .expect("reading from cursor won't fail");
assert_eq!(num_bytes, 5);
assert_eq!(buf, b"ipsum");
buf.clear();

// 游标在 EOF 处
let num_bytes = cursor.read_until(b'-', &mut buf)
    .expect("reading from cursor won't fail");
assert_eq!(num_bytes, 0);
assert_eq!(buf, b"");
Run
source

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

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

缓冲区的先前内容将被保留。为避免,追加,到缓冲区,您需要先将其 clear

该函数将从底层流中读取字节,直到找到换行符 (0xA 字节) 或 EOF。 一旦找到,直到并包括分隔符 (如果找到) 的所有字节都将被追加到 buf

如果成功,此函数将返回读取的字节总数。

如果此函数返回 Ok(0),则流已到达 EOF。

该函数正在阻塞,应谨慎使用:攻击者有可能连续发送字节而无需发送换行符或 EOF。

您可以使用 take 来限制读取的最大字节数。

Errors

该函数与 read_until 具有相同的错误语义,如果读取的字节无效,则还将返回错误。 如果遇到 I/O 错误,则 buf 可能包含一些已读取的字节,如果到目前为止读取的所有数据都是有效的 UTF-8。

Examples

std::io::Cursor 是一种实现了 BufRead 的类型。在这个例子中,我们使用 Cursor 读取一个字节切片中的所有行:

use std::io::{self, BufRead};

let mut cursor = io::Cursor::new(b"foo\nbar");
let mut buf = String::new();

// 游标在 'f'
let num_bytes = cursor.read_line(&mut buf)
    .expect("reading from cursor won't fail");
assert_eq!(num_bytes, 4);
assert_eq!(buf, "foo\n");
buf.clear();

// 游标在 'b'
let num_bytes = cursor.read_line(&mut buf)
    .expect("reading from cursor won't fail");
assert_eq!(num_bytes, 3);
assert_eq!(buf, "bar");
buf.clear();

// 游标在 EOF 处
let num_bytes = cursor.read_line(&mut buf)
    .expect("reading from cursor won't fail");
assert_eq!(num_bytes, 0);
assert_eq!(buf, "");
Run
source

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

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

这个函数返回的迭代器将返回 io::Result<Vec<u8>> 的实例。

返回的每个 vector 都不会在末尾有定界符字节。

只要 read_until 也产生错误,此函数就会产生错误。

Examples

std::io::Cursor 是一种实现了 BufRead 的类型。 在此示例中,我们使用 Cursor 遍历字节切片中的所有连字符分隔的段

use std::io::{self, BufRead};

let cursor = io::Cursor::new(b"lorem-ipsum-dolor");

let mut split_iter = cursor.split(b'-').map(|l| l.unwrap());
assert_eq!(split_iter.next(), Some(b"lorem".to_vec()));
assert_eq!(split_iter.next(), Some(b"ipsum".to_vec()));
assert_eq!(split_iter.next(), Some(b"dolor".to_vec()));
assert_eq!(split_iter.next(), None);
Run
source

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

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

从这个函数返回的迭代器将产生 io::Result<String> 的实例。 返回的每个字符串末尾都不会有换行符字节 (0xA 字节) 或 CRLF (0xD0xA 字节)。

Examples

std::io::Cursor 是一种实现了 BufRead 的类型。 在这个例子中,我们使用 Cursor 来遍历字节切片中的所有行。

use std::io::{self, BufRead};

let cursor = io::Cursor::new(b"lorem\nipsum\r\ndolor");

let mut lines_iter = cursor.lines().map(|l| l.unwrap());
assert_eq!(lines_iter.next(), Some(String::from("lorem")));
assert_eq!(lines_iter.next(), Some(String::from("ipsum")));
assert_eq!(lines_iter.next(), Some(String::from("dolor")));
assert_eq!(lines_iter.next(), None);
Run
Errors

迭代器的每一行都具有与 BufRead::read_line 相同的错误语义。

Implementors§

source§

impl BufRead for &[u8]

source§

impl BufRead for Empty

source§

impl BufRead for StdinLock<'_>

source§

impl<B: BufRead + ?Sized> BufRead for &mut B

source§

impl<B: BufRead + ?Sized> BufRead for Box<B>

source§

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

source§

impl<T> BufRead for Cursor<T>where T: AsRef<[u8]>,

source§

impl<T: BufRead> BufRead for Take<T>

1.9.0 · source§

impl<T: BufRead, U: BufRead> BufRead for Chain<T, U>