跳到主要内容

AsyncBufReadExt

搜索

特性 AsyncBufReadExt 

Source
pub trait AsyncBufReadExt: AsyncBufRead {
    // Provided methods
    fn read_until<'a>(
        &'a mut self,
        byte: u8,
        buf: &'a mut Vec<u8>,
    ) -> ReadUntil<'a, Self>
       where Self: Unpin { ... }
    fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>
       where Self: Unpin { ... }
    fn split(self, byte: u8) -> Split<Self>
       where Self: Sized + Unpin { ... }
    fn fill_buf(&mut self) -> FillBuf<'_, Self>
       where Self: Unpin { ... }
    fn consume(&mut self, amt: usize)
       where Self: Unpin { ... }
    fn lines(self) -> Lines<Self>
       where Self: Sized { ... }
}
展开描述

一个为 AsyncBufRead 类型添加实用方法的扩展 trait。

提供方法§

Source

fn read_until<'a>( &'a mut self, byte: u8, buf: &'a mut Vec<u8>, ) -> ReadUntil<'a, Self>
where Self: Unpin,

读取所有字节到 buf,直到遇到分隔符字节 byte 或 EOF。

等价于:

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

此函数从底层流读取字节,直到找到分隔符或 EOF。 一旦找到,分隔符(包括分隔符本身,如果找到)之前的所有字节都将追加到 buf

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

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

§Errors

此函数会忽略所有 ErrorKind::Interrupted 实例, 其它情况下会原样返回 fill_buf 返回的错误。

如果遇到 I/O 错误,那么到目前为止读取的所有字节都将保留在 buf 中, 并且其长度已相应调整。

§Cancel safety

如果在 tokio::select! 语句中将此方法作为事件, 而其他分支先完成,则可能已经部分读取了一些数据。 部分读取的字节会追加到 buf 中, 可以再次调用此方法继续读取,直到读到 byte 为止。

此方法返回读取的总字节数。 如果取消对 read_until 的调用之后再调用它继续读取, 计数器会被重置。

§示例

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

use tokio::io::AsyncBufReadExt;

use std::io::Cursor;

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

// cursor is at 'l'
let num_bytes = cursor.read_until(b'-', &mut buf)
    .await
    .expect("reading from cursor won't fail");

assert_eq!(num_bytes, 6);
assert_eq!(buf, b"lorem-");
buf.clear();

// cursor is at 'i'
let num_bytes = cursor.read_until(b'-', &mut buf)
    .await
    .expect("reading from cursor won't fail");

assert_eq!(num_bytes, 5);
assert_eq!(buf, b"ipsum");
buf.clear();

// cursor is at EOF
let num_bytes = cursor.read_until(b'-', &mut buf)
    .await
    .expect("reading from cursor won't fail");
assert_eq!(num_bytes, 0);
assert_eq!(buf, b"");
Source

fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>
where Self: Unpin,

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

等价于:

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

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

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

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

§Errors

此函数与 read_until 具有相同的错误语义, 并且当读取的字节不是有效的 UTF-8 时也会返回错误。 如果遇到 I/O 错误,且目前为止读取的所有数据都是有效的 UTF-8, 那么 buf 可能包含一些已读取的字节。

§Cancel safety

此方法不是可取消安全的。如果在 tokio::select! 语句中将其作为事件, 而其他分支先完成,则可能已经部分读取了一些数据, 这些数据将丢失。取消调用时 buf 的内容没有任何保证。 当前实现会将 buf 替换为空字符串,但未来可能会改变。

此函数的行为与 read_until 不同, 因为字符串要求仅包含有效的 utf-8。 如果你需要可取消安全的 read_line,有三种选择:

§示例

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

use tokio::io::AsyncBufReadExt;

use std::io::Cursor;

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

// cursor is at 'f'
let num_bytes = cursor.read_line(&mut buf)
    .await
    .expect("reading from cursor won't fail");

assert_eq!(num_bytes, 4);
assert_eq!(buf, "foo\n");
buf.clear();

// cursor is at 'b'
let num_bytes = cursor.read_line(&mut buf)
    .await
    .expect("reading from cursor won't fail");

assert_eq!(num_bytes, 3);
assert_eq!(buf, "bar");
buf.clear();

// cursor is at EOF
let num_bytes = cursor.read_line(&mut buf)
    .await
    .expect("reading from cursor won't fail");

assert_eq!(num_bytes, 0);
assert_eq!(buf, "");
Source

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

返回一个流,内容是按字节 byte 切分后的此读取器的片段。

此方法是 BufRead::split 的异步等价物。

此函数返回的流会产生 io::Result<Option<Vec<u8>>> 实例。 返回的每个向量末尾不会包含分隔符字节。

§Errors

流中每个项目的错误语义与 AsyncBufReadExt::read_until 相同。

§示例
use tokio::io::AsyncBufReadExt;

let mut segments = my_buf_read.split(b'f');

while let Some(segment) = segments.next_segment().await? {
    println!("length = {}", segment.len())
}
Source

fn fill_buf(&mut self) -> FillBuf<'_, Self>
where Self: Unpin,

返回内部缓冲区的内容,如果内部缓冲区为空,则从内部读取器填充更多数据。

此函数是较低级别的调用。要使其正常工作,需要与 consume 方法配对使用。 调用此方法时,其中的内容不会被视为已“读”, 因此随后调用 read 仍可能返回相同的内容。 因此,必须使用从此缓冲区消费的字节数调用 consume, 以确保相同的字节不会被返回两次。

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

等价于:

async fn fill_buf(&mut self) -> io::Result<&[u8]>;
§Errors

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

§Cancel safety

此方法是可取消安全的。如果在 tokio::select! 语句中将其作为事件, 而其他分支先完成,则可以保证没有数据被读取。

Source

fn consume(&mut self, amt: usize)
where Self: Unpin,

通知此缓冲区已有 amt 个字节被消费, 因此后续调用 read 时不应再返回这些字节。

此函数是较低级别的调用。要使其正常工作,需要与 fill_buf 方法配对使用。 此函数不执行任何 I/O 操作,它只是通知此对象: 从 fill_buf 返回的缓冲区中已有部分被消费, 不应再返回这些内容。因此,如果在调用此函数之前没有调用 fill_buf,则可能产生异常行为。

amt 必须小于由 fill_buf 返回的缓冲区中的字节数。

Source

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

返回此读取器各行的流。 此方法是 BufRead::lines 的异步等价物。

此函数返回的流会产生 io::Result<Option<String>> 实例。 返回的每个字符串末尾不会包含换行字节(0xA 字节)或 CRLF(0xD、0xA 字节)。

§Errors

流中每一行的错误语义与 AsyncBufReadExt::read_line 相同。

§示例

std::io::Cursor 是一个实现了 BufRead 的类型。 在此示例中,我们使用 Cursor 迭代字节切片中的所有行。

use tokio::io::AsyncBufReadExt;

use std::io::Cursor;

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

let mut lines = cursor.lines();

assert_eq!(lines.next_line().await.unwrap(), Some(String::from("lorem")));
assert_eq!(lines.next_line().await.unwrap(), Some(String::from("ipsum")));
assert_eq!(lines.next_line().await.unwrap(), Some(String::from("dolor")));
assert_eq!(lines.next_line().await.unwrap(), None);

动态兼容性§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

实现者§