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。
提供方法§
Sourcefn read_until<'a>(
&'a mut self,
byte: u8,
buf: &'a mut Vec<u8>,
) -> ReadUntil<'a, Self>where
Self: Unpin,
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"");Sourcefn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>where
Self: Unpin,
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,有三种选择:
- Call
read_untilwith a newline character and manually perform the utf-8 check. - The stream returned by
lineshas a cancellation safenext_linemethod. - Use
tokio_util::codec::LinesCodec.
§示例
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, "");Sourcefn split(self, byte: u8) -> Split<Self>
fn split(self, byte: u8) -> Split<Self>
返回一个流,内容是按字节 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())
}Sourcefn fill_buf(&mut self) -> FillBuf<'_, Self>where
Self: Unpin,
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! 语句中将其作为事件,
而其他分支先完成,则可以保证没有数据被读取。
Sourcefn lines(self) -> Lines<Self>where
Self: Sized,
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.