Expand description
Traits, helpers, and type definitions for asynchronous I/O functionality.
This module is the asynchronous version of std::io. Primarily, it
defines two traits, AsyncRead and AsyncWrite, which are asynchronous
versions of the Read and Write traits in the standard library.
§AsyncRead and AsyncWrite
Like the standard library’s Read and Write traits, AsyncRead and
AsyncWrite provide the most general interface for reading and writing
input and output. Unlike the standard library’s traits, however, they are
asynchronous — meaning that reading from or writing to a tokio::io
type will yield to the Tokio scheduler when IO is not ready, rather than
blocking. This allows other tasks to run while waiting on IO.
Another difference is that AsyncRead and AsyncWrite only contain
core methods needed to provide asynchronous reading and writing
functionality. Instead, utility methods are defined in the AsyncReadExt
and AsyncWriteExt extension traits. These traits are automatically
implemented for all values that implement AsyncRead and AsyncWrite
respectively.
End users will rarely interact directly with AsyncRead and
AsyncWrite. Instead, they will use the async functions defined in the
extension traits. Library authors are expected to implement AsyncRead
and AsyncWrite in order to provide types that behave like byte streams.
Even with these differences, Tokio’s AsyncRead and AsyncWrite traits
can be used in almost exactly the same manner as the standard library’s
Read and Write. Most types in the standard library that implement Read
and Write have asynchronous equivalents in tokio that implement
AsyncRead and AsyncWrite, such as File and TcpStream.
For example, the standard library documentation introduces Read by
demonstrating reading some bytes from a std::fs::File. We
can do the same with 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
Byte-based interfaces are unwieldy and can be inefficient, as we’d need to be
making near-constant calls to the operating system. To help with this,
std::io comes with support for buffered readers and writers,
and therefore, tokio::io does as well.
Tokio provides an async version of the std::io::BufRead trait,
AsyncBufRead; and async BufReader and BufWriter structs, which
wrap readers and writers. These wrappers use a buffer, reducing the number
of calls and providing nicer methods for accessing exactly what you want.
For example, BufReader works with the AsyncBufRead trait to add
extra methods to any async reader:
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 doesn’t add any new ways of writing; it just buffers every call
to write. However, you must flush
BufWriter to ensure that any buffered data is written.
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
Because they are traits, we can implement AsyncRead and AsyncWrite for
our own types, as well. Note that these traits must only be implemented for
non-blocking I/O types that integrate with the futures type system. In
other words, these types must never block the thread, and instead the
current task is notified when the I/O resource is ready.
§Conversion to and from Stream/Sink
It is often convenient to encapsulate the reading and writing of bytes in a
Stream or Sink of data.
Tokio provides simple wrappers for converting AsyncRead to Stream
and vice-versa in the tokio-util crate, see ReaderStream and
StreamReader.
There are also utility traits that abstract the asynchronous buffering
necessary to write your own adaptors for encoding and decoding bytes to/from
your structured data, allowing to transform something that implements
AsyncRead/AsyncWrite into a Stream/Sink, see Decoder and
Encoder in the tokio-util::codec module.
§Standard input and output
Tokio provides asynchronous APIs to standard input, output, and error.
These APIs are very similar to the ones provided by std, but they also
implement AsyncRead and AsyncWrite.
Note that the standard input / output APIs must be used from the context of the Tokio runtime, as they require Tokio-specific features to function. Calling these functions outside of a Tokio runtime will panic.
§std re-exports
Additionally, Error, ErrorKind, Result, and SeekFrom are
re-exported from std::io for ease of use.
Re-exports§
pub use std::io::Error;pub use std::io::ErrorKind;pub use std::io::Result;pub use std::io::SeekFrom;
Modules§
- unix
- Asynchronous IO structures specific to Unix-like operating systems.
Structs§
- BufReader
- The
BufReaderstruct adds buffering to any reader. - BufStream
- Wraps a type that is
AsyncWriteandAsyncRead, and buffers its input and output. - BufWriter
- Wraps a writer and buffers its output.
- Duplex
Stream - A bidirectional pipe to read and write bytes in memory.
- Empty
Emptyignores any data written viaAsyncWrite, and will always be empty (returning zero bytes) when read viaAsyncRead.- Interest
- Readiness event interest.
- Join
- Joins two values implementing
AsyncReadandAsyncWriteinto a single handle. - Lines
- Reads lines from an
AsyncBufRead. - ReadBuf
- A wrapper around a byte buffer that is incrementally filled and initialized.
- Read
Half - The readable half of a value returned from
split. - Ready
- Describes the readiness state of an I/O resources.
- Repeat
- An async reader which yields one byte over and over and over and over and over and…
- Simplex
Stream - A unidirectional pipe to read and write bytes in memory.
- Sink
- An async writer which will move data into the void.
- Split
- Splitter for the
splitmethod. - Take
- Stream for the
takemethod. - Write
Half - The writable half of a value returned from
split.
Traits§
- Async
BufRead - Reads bytes asynchronously.
- Async
BufRead Ext - An extension trait which adds utility methods to
AsyncBufReadtypes. - Async
Read - Reads bytes from a source.
- Async
Read Ext - Reads bytes from a source.
- Async
Seek - Seek bytes asynchronously.
- Async
Seek Ext - An extension trait that adds utility methods to
AsyncSeektypes. - Async
Write - Writes bytes asynchronously.
- Async
Write Ext - Writes bytes to a sink.
Functions§
- copy
- Asynchronously copies the entire contents of a reader into a writer.
- copy_
bidirectional - Copies data in both directions between
aandb. - copy_
bidirectional_ with_ sizes - Copies data in both directions between
aandbusing buffers of the specified size. - copy_
buf - Asynchronously copies the entire contents of a reader into a writer.
- duplex
- Create a new pair of
DuplexStreams that act like a pair of connected sockets. - empty
- Creates a value that is always at EOF for reads, and ignores all data written.
- join
- Join two values implementing
AsyncReadandAsyncWriteinto a single handle. - repeat
- Creates an instance of an async reader that infinitely repeats one byte.
- simplex
- Creates unidirectional buffer that acts like in memory pipe.
- sink
- Creates an instance of an async writer which will successfully consume all data.
- split
- Splits a single value implementing
AsyncRead + AsyncWriteinto separateAsyncReadandAsyncWritehandles.