展开描述
用于异步 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(())
}§Buffered Readers and 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 资源就绪时通知当前任务。
§Conversion to and from 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;
结构体§
- Interest
- Readiness event interest.
- ReadBuf
- A wrapper around a byte buffer that is incrementally filled and initialized.
- Ready
- Describes the readiness state of an I/O resources.
trait§
- Async
BufRead - Reads bytes asynchronously.
- Async
Read - Reads bytes from a source.
- Async
Seek - Seek bytes asynchronously.
- Async
Write - Writes bytes asynchronously.