Модуль io
Трейты, вспомогательные средства и определения типов для асинхронного ввода-вывода.
Этот модуль — асинхронная версия std::io. В основном в нём определены два трейта: AsyncRead и AsyncWrite, представляющие собой асинхронные версии трейтов Read и Write из стандартной библиотеки.
AsyncRead и AsyncWrite
Подобно трейтам Read и Write из стандартной библиотеки, AsyncRead и AsyncWrite предоставляют наиболее общий интерфейс для чтения и записи данных. Однако, в отличие от трейтов стандартной библиотеки, они являются асинхронными — это означает, что чтение из типа tokio::io или запись в него передаст управление планировщику Tokio, если ввод-вывод не готов, вместо того чтобы блокировать выполнение. Это позволяет запускать другие задачи, пока выполняются операции ввода-вывода.
Ещё одно отличие состоит в том, что AsyncRead и AsyncWrite содержат только основные методы, необходимые для асинхронного чтения и записи. Вспомогательные методы определены в трейтах-расширениях AsyncReadExt и AsyncWriteExt. Эти трейты автоматически реализуются для всех значений, реализующих соответственно AsyncRead и AsyncWrite.
Конечным пользователям редко приходится напрямую взаимодействовать с AsyncRead и AsyncWrite. Вместо этого они используют асинхронные функции, определённые в трейтах-расширениях. Ожидается, что авторы библиотек будут реализовывать AsyncRead и AsyncWrite, чтобы предоставлять типы, работающие как потоки байтов.
Несмотря на эти различия, трейты Tokio AsyncRead и AsyncWrite можно использовать почти так же, как Read и Write из стандартной библиотеки. Большинство типов стандартной библиотеки, реализующих Read и Write, имеют асинхронные аналоги в tokio, реализующие AsyncRead и AsyncWrite, например File и TcpStream.
Например, в документации стандартной библиотеки Read вводится с помощью примера чтения байтов из std::fs::File. То же самое можно сделать с помощью 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(())
}Буферизованные средства чтения и записи
Интерфейсы на основе байтов неудобны и могут быть неэффективными, поскольку нам пришлось бы почти постоянно обращаться к операционной системе. Для решения этой проблемы std::io поддерживает буферизованные средства чтения и записи, и tokio::io тоже.
Tokio предоставляет асинхронную версию трейта std::io::BufRead — AsyncBufRead, а также асинхронные структуры BufReader и BufWriter, оборачивающие средства чтения и записи. Эти обёртки используют буфер, уменьшая количество вызовов и предоставляя более удобные методы для доступа именно к нужным данным.
Например, BufReader работает с трейтом AsyncBufRead, добавляя дополнительные методы для любого асинхронного средства чтения:
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. Однако, чтобы гарантировать запись всех буферизованных данных, необходимо вызвать метод сброса буфера у 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(())
}Реализация AsyncRead и AsyncWrite
Поскольку это трейты, мы можем реализовать AsyncRead и AsyncWrite и для собственных типов. Обратите внимание, что эти трейты следует реализовывать только для неблокирующих типов ввода-вывода, интегрированных с системой типов futures. Иными словами, эти типы никогда не должны блокировать поток; вместо этого текущая задача получает уведомление, когда ресурс ввода-вывода готов.
Преобразование в Stream/Sink и обратно
Часто бывает удобно инкапсулировать чтение и запись байтов в Stream или Sink данных.
Tokio предоставляет в крейте tokio-util простые обёртки для преобразования AsyncRead в Stream и обратно. См. ReaderStream и StreamReader.
Также доступны вспомогательные трейты, абстрагирующие асинхронную буферизацию, необходимую для создания собственных адаптеров кодирования и декодирования байтов в структурированные данные и обратно. Они позволяют преобразовать объект, реализующий AsyncRead/AsyncWrite, в Stream/Sink. См. Decoder и Encoder в модуле tokio-util::codec.
Стандартный ввод и вывод
Tokio предоставляет асинхронные API для стандартных потоков ввода, вывода и ошибок. Эти API очень похожи на предоставляемые std, но также реализуют AsyncRead и AsyncWrite.
Обратите внимание, что API стандартных потоков ввода-вывода необходимо использовать в контексте среды выполнения Tokio, поскольку для работы им нужны специфичные для Tokio функции. Вызов этих функций вне среды выполнения Tokio вызовет панику.
Реэкспорты std
Кроме того, Error, ErrorKind, Result и SeekFrom реэкспортируются из std::io для удобства использования.
Реэкспорты
pub use std::io::Error;pub use std::io::ErrorKind;pub use std::io::Result;pub use std::io::SeekFrom;
Модули
-
bsd
FreeBSD и только net - Типы ввода-вывода, специфичные для BSD.
-
unix
Unix и только net - Асинхронные структуры ввода-вывода, специфичные для Unix-подобных операционных систем.
Структуры
-
BufReader
Только io-util - Структура
BufReaderдобавляет буферизацию любому средству чтения. -
BufStream
Только io-util - Оборачивает тип, реализующий
AsyncWriteиAsyncRead, и буферизует его ввод и вывод. -
BufWriter
Только io-util - Оборачивает средство записи и буферизует его вывод.
-
Chain
Только io-util - Поток для метода
chain. -
Duplex
Stream Только io-util - Двунаправленный канал для чтения и записи байтов в памяти.
-
Empty
Только io-util -
Emptyигнорирует любые данные, записанные черезAsyncWrite, и всегда остаётся пустым (возвращает ноль байтов) при чтении черезAsyncRead. -
Interest
Только netилиtokio_unstable, Linux,fs,io-uringиrt - Интерес к событию готовности.
-
Join
Только io-util - Объединяет два значения, реализующих
AsyncReadиAsyncWrite, в один дескриптор. -
Lines
Только io-util - Читает строки из
AsyncBufRead. - ReadBuf
- Обёртка над буфером байтов, который заполняется и инициализируется постепенно.
-
Read
Half Только io-util - Читаемая половина значения, возвращённого функцией
split. -
Ready
Только netилиtokio_unstable, Linux,fs,io-uringиrt - Описывает состояние готовности ресурса ввода-вывода.
-
Repeat
Только io-util - Асинхронное средство чтения, которое снова и снова выдаёт один байт…
-
Simplex
Stream Только io-util - Однонаправленный канал для чтения и записи байтов в памяти.
-
Sink
Только io-util - Асинхронное средство записи, которое отправляет данные в никуда.
-
Split
Только io-util - Разделитель для метода
split. -
Stderr
Только io-std - Дескриптор стандартного потока ошибок процесса.
-
Stdin
Только io-std - Дескриптор стандартного потока ввода процесса.
-
Stdout
Только io-std - Дескриптор стандартного потока вывода процесса.
-
Take
Только io-util - Поток для метода
take. -
Write
Half Только io-util - Записываемая половина значения, возвращённого функцией
split.
Трейты
- Async
BufRead - Асинхронно читает байты.
-
Async
BufRead Ext Только io-util - Трейт-расширение, добавляющий вспомогательные методы типам
AsyncBufRead. - Async
Read - Читает байты из источника.
-
Async
Read Ext Только io-util - Читает байты из источника.
- Async
Seek - Асинхронно перемещается по байтам.
-
Async
Seek Ext Только io-util - Трейт-расширение, добавляющий вспомогательные методы типам
AsyncSeek. - Async
Write - Асинхронно записывает байты.
-
Async
Write Ext Только io-util - Записывает байты в приёмник.
Функции
-
copy
Только io-util - Асинхронно копирует всё содержимое средства чтения в средство записи.
-
copy_
bidirectional Только io-util - Копирует данные в обоих направлениях между
aиb. -
copy_
bidirectional_ with_ sizes Только io-util - Копирует данные в обоих направлениях между
aиb, используя буферы указанного размера. -
copy_
buf Только io-util - Асинхронно копирует всё содержимое средства чтения в средство записи.
-
duplex
Только io-util - Создаёт пару
DuplexStream, работающих как пара соединённых сокетов. -
empty
Только io-util - Создаёт значение, которое при чтении всегда возвращает EOF и игнорирует все записанные данные.
-
join
Только io-util - Объединяет два значения, реализующих
AsyncReadиAsyncWrite, в один дескриптор. -
repeat
Только io-util - Создаёт экземпляр асинхронного средства чтения, бесконечно повторяющего один байт.
-
simplex
Только io-util - Создаёт однонаправленный буфер, работающий как канал в памяти.
-
sink
Только io-util - Создаёт экземпляр асинхронного средства записи, которое успешно принимает все данные.
-
split
Только io-util - Разделяет значение, реализующее
AsyncRead + AsyncWrite, на отдельные дескрипторыAsyncReadиAsyncWrite. -
stderr
Только io-std - Создаёт новый дескриптор стандартного потока ошибок текущего процесса.
-
stdin
Только io-std - Создаёт новый дескриптор стандартного потока ввода текущего процесса.
-
stdout
Только io-std - Создаёт новый дескриптор стандартного потока вывода текущего процесса.
MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/io/index.html