展开描述
异步 I/O 功能的 trait、辅助函数和类型定义。
此模块是 std::io 的异步版本。
它主要定义了两个 trait:AsyncRead 和 AsyncWrite,
它们是标准库中 Read 和 Write trait 的异步版本。
§AsyncRead and AsyncWrite
与标准库的 Read 和 Write trait 类似,AsyncRead 和
AsyncWrite 提供了用于读取和写入输入/输出
的最通用接口。
但与标准库的 trait 不同,它们
是异步的——这意味着对 tokio::io
类型进行读或写时,当 IO 还未就绪时会让出
给 Tokio 调度器,而不是阻塞。
这允许其他任务在等待 IO 时运行。
另一个区别是,AsyncRead 和 AsyncWrite 仅包含提供异步读写功能所需的核心方法。
而工具方法则定义在 AsyncReadExt 和 AsyncWriteExt 扩展 trait 中。
这些 trait 会自动为实现了 AsyncRead 和 AsyncWrite 的所有值实现。
最终用户很少会直接与 AsyncRead 和 AsyncWrite 交互,
而是使用扩展 trait 中定义的异步函数。
库的作者需要实现 AsyncRead 和 AsyncWrite,
以便提供表现为字节流行为的类型。
尽管存在这些差异,Tokio 的 AsyncRead 和 AsyncWrite trait
几乎可以以与标准库的 Read 和 Write 完全相同的方式使用。
标准库中大多数实现 Read 和 Write 的类型,
在 tokio 中都有实现了 AsyncRead 和 AsyncWrite 的异步等价物,
例如 File 和 TcpStream。
例如,标准库文档通过演示从 std::fs::File 读取一些字节来介绍 Read。
我们也可以用 tokio::fs::File 做到同样的事情:
use tokio::io::{self, AsyncReadExt};
use tokio::fs::File;
#[tokio::main]
async fn main() -> io::Result<()> {
let mut f = File::open("foo.txt").await?;
let mut buffer = [0; 10];
// read up to 10 bytes
let n = f.read(&mut buffer).await?;
println!("The bytes: {:?}", &buffer[..n]);
Ok(())
}§带缓冲的 Readers 与 Writers
基于字节的接口使用起来很繁琐,效率也可能很低,因为我们几乎需要不停地调用操作系统。
为了解决这个问题,std::io 提供了对缓冲读取器和写入器的支持,
因此 tokio::io 也提供了这样的支持。
Tokio 提供了 std::io::BufRead trait 的异步版本
AsyncBufRead,以及异步的 BufReader 和 BufWriter 结构体,
它们包装了读取器和写入器。这些包装器使用缓冲区,减少了调用次数,
并提供了更方便的方法来精确访问你想要的内容。
例如,BufReader 与 AsyncBufRead trait 一起工作,
为任何异步读取器添加额外的方法:
use tokio::io::{self, BufReader, AsyncBufReadExt};
use tokio::fs::File;
#[tokio::main]
async fn main() -> io::Result<()> {
let f = File::open("foo.txt").await?;
let mut reader = BufReader::new(f);
let mut buffer = String::new();
// read a line into buffer
reader.read_line(&mut buffer).await?;
println!("{}", buffer);
Ok(())
}BufWriter 不会添加任何新的写入方式;它只是缓冲对
write 的每次调用。
然而,你必须 flush BufWriter 以确保所有缓冲的数据都被写入。
use tokio::io::{self, BufWriter, AsyncWriteExt};
use tokio::fs::File;
#[tokio::main]
async fn main() -> io::Result<()> {
let f = File::create("foo.txt").await?;
{
let mut writer = BufWriter::new(f);
// Write a byte to the buffer.
writer.write(&[42u8]).await?;
// Flush the buffer before it goes out of scope.
writer.flush().await?;
} // Unless flushed or shut down, the contents of the buffer is discarded on drop.
Ok(())
}§Implementing AsyncRead and AsyncWrite
因为它们是 trait,我们也可以为自己的类型实现 AsyncRead 和 AsyncWrite。
请注意,这些 trait 只能为与 futures 类型系统集成的非阻塞 I/O 类型实现。
换句话说,这些类型绝不能阻塞线程,
而应在 I/O 资源就绪时通知当前任务。
§Stream/Sink 之间的相互转换
通常,将字节的读写封装在数据的
Stream 或 Sink 中会很方便。
Tokio 在 tokio-util crate 中提供了简单的包装器,
用于在 AsyncRead 与 Stream 之间互相转换,
请参阅 ReaderStream 和
StreamReader。
还有一些工具 trait 抽象了编写自己的字节与结构化数据编码/解码适配器所需的异步缓冲,
允许将实现 AsyncRead/AsyncWrite 的对象转换为
Stream/Sink,
请参阅 tokio-util::codec 模块中的
Decoder 和
Encoder。
§Standard input and output
Tokio 提供了标准输入、输出和错误的异步 API。
这些 API 与 std 提供的 API 非常相似,但它们还实现了
AsyncRead 和 AsyncWrite。
请注意,标准输入/输出 API 必须在 Tokio 运行时的上下文中使用, 因为它们需要 Tokio 特有的功能才能工作。 在 Tokio 运行时之外调用这些函数将导致 panic。
§std re-exports
重新导出§
pub use std::io::Error;pub use std::io::ErrorKind;pub use std::io::Result;pub use std::io::SeekFrom;
结构体§
- BufReader
BufReader结构体 为任何 reader 添加缓冲。- BufStream
- 包装一个同时实现
AsyncWrite和AsyncRead的类型, 并对其输入和输出进行缓冲。 - BufWriter
- 包装一个 writer 并缓冲其输出。
- Chain
chain方法所用的流。- Duplex
Stream - 用于在内存中读写字节的双向管道。
- Empty
Empty忽略通过AsyncWrite写入的任何数据, 并在通过AsyncRead读取时始终为空 (返回零字节)。- Interest
- 就绪事件兴趣位。
- Join
- 将实现
AsyncRead和AsyncWrite的两个值 合并为单个句柄。 - Lines
- 从
AsyncBufRead读取行。 - ReadBuf
- 一个字节缓冲区的封装,会被增量填充和初始化。
- Read
Half - 从
split返回的值的可读一半。 - Ready
- 描述 I/O 资源的就绪状态。
- Repeat
- 一个异步 reader, 其反复、反复、反复地 产出一个字节。
- Simplex
Stream - 用于在内存中读写字节的单向管道。
- Sink
- 一个将数据移入空白的异步 writer。
- Split
split方法所用的分割器。- Stderr
- 进程标准错误流的句柄。
- Stdin
- 进程标准输入流的句柄。
- Stdout
- 进程标准输出流的句柄。
- Take
take方法所用的流。- Write
Half - 从
split返回的值的可写一半。
特性§
- Async
BufRead - 异步地读取字节。
- Async
BufRead Ext - 为
AsyncBufRead类型添加实用方法的扩展 trait。 - Async
Read - 从一个数据源异步地读取字节。
- Async
Read Ext - 从一个数据源异步地读取字节。
- Async
Seek - 异步地定位字节。
- Async
Seek Ext - 为
AsyncSeek类型添加实用方法的扩展 trait。 - Async
Write - 异步地写入字节。
- Async
Write Ext - 将字节写入 sink。
函数§
- copy
- 异步地将 reader 的全部内容 复制到 writer。
- copy_
bidirectional - 在
a和b之间 双向复制数据。 - copy_
bidirectional_ with_ sizes - 使用指定大小的缓冲区,
在
a和b之间 双向复制数据。 - copy_
buf - 异步地将 reader 的全部内容 复制到 writer。
- duplex
- 创建一个新的
DuplexStream对, 其行为类似一对连接的 socket。 - empty
- 创建一个 读取时始终处于 EOF、 且忽略所有写入数据的值。
- join
- 将实现
AsyncRead和AsyncWrite的两个值 合并为单个句柄。 - repeat
- 创建一个 无限重复单个字节的异步 reader 实例。
- simplex
- 创建一个 行为类似内存管道的单向缓冲区。
- sink
- 创建一个 将成功消费所有数据的 异步 writer 实例。
- split
- 将一个
同时实现
AsyncRead + AsyncWrite的值 分割为 单独的AsyncRead和AsyncWrite句柄。 - stderr
- 构造一个 当前进程标准错误的 新句柄。
- stdin
- 构造一个 当前进程标准输入的 新句柄。
- stdout
- 构造一个 当前进程标准输出的 新句柄。