概述
futures-io这个类库主要包含 AsyncRead
, AsyncWrite
, AsyncSeek
,AsyncBufRead
traits,对应同步标准库里的std::io::{Read, Write, Seek, BufRead}
,主要区别是这些trait与异步系统集成在一起。
AsyncRead
异步读取字节。类似std::io::Read
,poll_read
不同于Read::read
,当前任务会加入到executor执行队列并等待唤醒,在数据尚不可用的情况下返回而不是阻塞调用线程。
pub trait AsyncRead {
#[cfg(feature = "read-initializer")]
#[inline]
unsafe fn initializer(&self) -> Initializer {
Initializer::zeroing()
}
/// 尝试从对象中读取数据到buf
/// 成功,则返回`Poll::Ready(Ok(num_bytes_read))`
/// 如果没有数据可读取,则返回`Poll::Pending` 并安排当前任务(via `cx.waker().wake_by_ref()`)在可读或关闭时接收通知
fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
-> Poll<Result<usize>>;
fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
-> Poll<Result<usize>>
{
for b in bufs {
if !b.is_empty() {
return self.poll_read(cx, b);
}
}
self.poll_read(cx, &mut [])
}
}
AsyncWrite
异步写字节。类似std::io::Write
,poll_write
不同于Write::write
,当前任务会加入到executor执行队列并等待唤醒,在数据尚不可用的情况下返回而不是阻塞调用线程。
pub trait AsyncWrite {
/// 尝试将buf中的字节写入到AsyncWrite
/// 成功,则返回`Poll::Ready(Ok(num_bytes_written))`
/// 如果对象尚未准备好写,则返回`Poll::Pending` 并安排当前任务(via `cx.waker().wake_by_ref()`)在可写或关闭时接收通知
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
-> Poll<Result<usize>>;
fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>])
-> Poll<Result<usize>>
{
for b in bufs {
if !b.is_empty() {
return self.poll_write(cx, b);
}
}
self.poll_write(cx, &[])
}
/// 尝试刷新对象,确保所有的数据到达目的地
/// 成功,则返回`Poll::Ready(Ok(()))`
/// 如果无法立即完成刷新,则返回`Poll::Pending` 并安排当前任务(via `cx.waker().wake_by_ref()`)在对象可以进行刷新时接收通知
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>;
/// 尝试关闭对象
/// 如果成功,则返回`Poll::Ready(Ok(()))`
/// 如果无法立即关闭,则返回`Poll::Pending` 并安排当前任务(via `cx.waker().wake_by_ref()`)在对象可以关闭时接收通知
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>;
}
AsyncSeek
异步查找字节。类似std::io::Seek
,poll_seek
不同于Seek::seek
,当前任务会加入到executor执行队列并等待唤醒,在数据尚不可用的情况下返回而不是阻塞调用线程。
pub trait AsyncSeek {
/// Attempt to seek to an offset, in bytes, in a stream.
/// 尝试在流中查找以字节为单位的偏移量
/// 允许在流的末端进行查找,但行为由实现定义
/// 如果seek操作成功完成,从流的开头返回新的位置,该位置以后可以与[`SeekFrom::Start`]一起使用
/// 查找负偏移量被视作是错误
fn poll_seek(self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom)
-> Poll<Result<u64>>;
}
AsyncBufRead
异步读取字节。类似std::io::BufRead
,poll_fill_buf
不同于`BufRead::fill_buf``,当前任务会加入到executor执行队列并等待唤醒,在数据尚不可用的情况下返回而不是阻塞调用线程。
pub trait AsyncBufRead: AsyncRead {
/// 尝试返回内部缓冲区内容,如果内部缓冲区为空,则用内部reader的更多数据填充它
/// 如果成功则返回`Poll::Ready(Ok(buf))`
/// 如果没有数据可读取,则返回`Poll::Pending` 并安排当前任务(via `cx.waker().wake_by_ref()`)在可读或关闭时接收通知
/// 这个函数一个低级别的调用,通常与consume方法配合才能正常运行
/// 调用此方法时,任何内容都不会被“read”,因为稍后调用[`poll_read`]可能会返回相同的内容。因此,必须使用从此缓冲区消耗的字节数来调用[`consume`],以确保字节永远不会返回两次。
/// 返回空缓冲区,则表示流已到达EOF
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>)
-> Poll<Result<&[u8]>>;
/// 告诉此缓冲区,“amt”字节已从缓冲区中消耗掉,因此在调用[`poll_read`]时不再应返回它们。
/// 这个函数一个低级别的调用,通常与poll_fill_buf方法配合才能正常运行
/// 此函数不执行任何I/O,只是通知此对象其缓冲区有一定数据,
/// 从[`poll_fill_buf`]返回的内容已被使用,不应再返回。
/// 因此,如果在调用[poll_fill_buf]之前未对其进行调用,则此函数可能会做一些奇怪的事情。
/// [`poll_read`]: AsyncRead::poll_read
/// [`poll_fill_buf`]: AsyncBufRead::poll_fill_buf
fn consume(self: Pin<&mut Self>, amt: usize);
}