tokio\io/mod.rs
1//! Traits, helpers, and type definitions for asynchronous I/O functionality.
2//!
3//! This module is the asynchronous version of `std::io`. Primarily, it
4//! defines two traits, [`AsyncRead`] and [`AsyncWrite`], which are asynchronous
5//! versions of the [`Read`] and [`Write`] traits in the standard library.
6//!
7//! # `AsyncRead` and `AsyncWrite`
8//!
9//! Like the standard library's [`Read`] and [`Write`] traits, [`AsyncRead`] and
10//! [`AsyncWrite`] provide the most general interface for reading and writing
11//! input and output. Unlike the standard library's traits, however, they are
12//! _asynchronous_ — meaning that reading from or writing to a `tokio::io`
13//! type will _yield_ to the Tokio scheduler when IO is not ready, rather than
14//! blocking. This allows other tasks to run while waiting on IO.
15//!
16//! Another difference is that `AsyncRead` and `AsyncWrite` only contain
17//! core methods needed to provide asynchronous reading and writing
18//! functionality. Instead, utility methods are defined in the [`AsyncReadExt`]
19//! and [`AsyncWriteExt`] extension traits. These traits are automatically
20//! implemented for all values that implement `AsyncRead` and `AsyncWrite`
21//! respectively.
22//!
23//! End users will rarely interact directly with `AsyncRead` and
24//! `AsyncWrite`. Instead, they will use the async functions defined in the
25//! extension traits. Library authors are expected to implement `AsyncRead`
26//! and `AsyncWrite` in order to provide types that behave like byte streams.
27//!
28//! Even with these differences, Tokio's `AsyncRead` and `AsyncWrite` traits
29//! can be used in almost exactly the same manner as the standard library's
30//! `Read` and `Write`. Most types in the standard library that implement `Read`
31//! and `Write` have asynchronous equivalents in `tokio` that implement
32//! `AsyncRead` and `AsyncWrite`, such as [`File`] and [`TcpStream`].
33//!
34//! For example, the standard library documentation introduces `Read` by
35//! [demonstrating][std_example] reading some bytes from a [`std::fs::File`]. We
36//! can do the same with [`tokio::fs::File`][`File`]:
37//!
38//! ```no_run
39//! # #[cfg(not(target_family = "wasm"))]
40//! # {
41//! use tokio::io::{self, AsyncReadExt};
42//! use tokio::fs::File;
43//!
44//! #[tokio::main]
45//! async fn main() -> io::Result<()> {
46//! let mut f = File::open("foo.txt").await?;
47//! let mut buffer = [0; 10];
48//!
49//! // read up to 10 bytes
50//! let n = f.read(&mut buffer).await?;
51//!
52//! println!("The bytes: {:?}", &buffer[..n]);
53//! Ok(())
54//! }
55//! # }
56//! ```
57//!
58//! [`File`]: crate::fs::File
59//! [`TcpStream`]: crate::net::TcpStream
60//! [`std::fs::File`]: std::fs::File
61//! [std_example]: std::io#read-and-write
62//!
63//! ## Buffered Readers and Writers
64//!
65//! Byte-based interfaces are unwieldy and can be inefficient, as we'd need to be
66//! making near-constant calls to the operating system. To help with this,
67//! `std::io` comes with [support for _buffered_ readers and writers][stdbuf],
68//! and therefore, `tokio::io` does as well.
69//!
70//! Tokio provides an async version of the [`std::io::BufRead`] trait,
71//! [`AsyncBufRead`]; and async [`BufReader`] and [`BufWriter`] structs, which
72//! wrap readers and writers. These wrappers use a buffer, reducing the number
73//! of calls and providing nicer methods for accessing exactly what you want.
74//!
75//! For example, [`BufReader`] works with the [`AsyncBufRead`] trait to add
76//! extra methods to any async reader:
77//!
78//! ```no_run
79//! # #[cfg(not(target_family = "wasm"))]
80//! # {
81//! use tokio::io::{self, BufReader, AsyncBufReadExt};
82//! use tokio::fs::File;
83//!
84//! #[tokio::main]
85//! async fn main() -> io::Result<()> {
86//! let f = File::open("foo.txt").await?;
87//! let mut reader = BufReader::new(f);
88//! let mut buffer = String::new();
89//!
90//! // read a line into buffer
91//! reader.read_line(&mut buffer).await?;
92//!
93//! println!("{}", buffer);
94//! Ok(())
95//! }
96//! # }
97//! ```
98//!
99//! [`BufWriter`] doesn't add any new ways of writing; it just buffers every call
100//! to [`write`](crate::io::AsyncWriteExt::write). However, you **must** flush
101//! [`BufWriter`] to ensure that any buffered data is written.
102//!
103//! ```no_run
104//! # #[cfg(not(target_family = "wasm"))]
105//! # {
106//! use tokio::io::{self, BufWriter, AsyncWriteExt};
107//! use tokio::fs::File;
108//!
109//! #[tokio::main]
110//! async fn main() -> io::Result<()> {
111//! let f = File::create("foo.txt").await?;
112//! {
113//! let mut writer = BufWriter::new(f);
114//!
115//! // Write a byte to the buffer.
116//! writer.write(&[42u8]).await?;
117//!
118//! // Flush the buffer before it goes out of scope.
119//! writer.flush().await?;
120//!
121//! } // Unless flushed or shut down, the contents of the buffer is discarded on drop.
122//!
123//! Ok(())
124//! }
125//! # }
126//! ```
127//!
128//! [stdbuf]: std::io#bufreader-and-bufwriter
129//! [`std::io::BufRead`]: std::io::BufRead
130//! [`AsyncBufRead`]: crate::io::AsyncBufRead
131//! [`BufReader`]: crate::io::BufReader
132//! [`BufWriter`]: crate::io::BufWriter
133//!
134//! ## Implementing `AsyncRead` and `AsyncWrite`
135//!
136//! Because they are traits, we can implement [`AsyncRead`] and [`AsyncWrite`] for
137//! our own types, as well. Note that these traits must only be implemented for
138//! non-blocking I/O types that integrate with the futures type system. In
139//! other words, these types must never block the thread, and instead the
140//! current task is notified when the I/O resource is ready.
141//!
142//! ## Conversion to and from Stream/Sink
143//!
144//! It is often convenient to encapsulate the reading and writing of bytes in a
145//! [`Stream`] or [`Sink`] of data.
146//!
147//! Tokio provides simple wrappers for converting [`AsyncRead`] to [`Stream`]
148//! and vice-versa in the [tokio-util] crate, see [`ReaderStream`] and
149//! [`StreamReader`].
150//!
151//! There are also utility traits that abstract the asynchronous buffering
152//! necessary to write your own adaptors for encoding and decoding bytes to/from
153//! your structured data, allowing to transform something that implements
154//! [`AsyncRead`]/[`AsyncWrite`] into a [`Stream`]/[`Sink`], see [`Decoder`] and
155//! [`Encoder`] in the [tokio-util::codec] module.
156//!
157//! [tokio-util]: https://docs.rs/tokio-util
158//! [tokio-util::codec]: https://docs.rs/tokio-util/latest/tokio_util/codec/index.html
159//!
160//! # Standard input and output
161//!
162//! Tokio provides asynchronous APIs to standard [input], [output], and [error].
163//! These APIs are very similar to the ones provided by `std`, but they also
164//! implement [`AsyncRead`] and [`AsyncWrite`].
165//!
166//! Note that the standard input / output APIs **must** be used from the
167//! context of the Tokio runtime, as they require Tokio-specific features to
168//! function. Calling these functions outside of a Tokio runtime will panic.
169//!
170//! [input]: fn@stdin
171//! [output]: fn@stdout
172//! [error]: fn@stderr
173//!
174//! # `std` re-exports
175//!
176//! Additionally, [`Error`], [`ErrorKind`], [`Result`], and [`SeekFrom`] are
177//! re-exported from `std::io` for ease of use.
178//!
179//! [`AsyncRead`]: trait@AsyncRead
180//! [`AsyncWrite`]: trait@AsyncWrite
181//! [`AsyncReadExt`]: trait@AsyncReadExt
182//! [`AsyncWriteExt`]: trait@AsyncWriteExt
183//! ["codec"]: https://docs.rs/tokio-util/latest/tokio_util/codec/index.html
184//! [`Encoder`]: https://docs.rs/tokio-util/latest/tokio_util/codec/trait.Encoder.html
185//! [`Decoder`]: https://docs.rs/tokio-util/latest/tokio_util/codec/trait.Decoder.html
186//! [`ReaderStream`]: https://docs.rs/tokio-util/latest/tokio_util/io/struct.ReaderStream.html
187//! [`StreamReader`]: https://docs.rs/tokio-util/latest/tokio_util/io/struct.StreamReader.html
188//! [`Error`]: struct@Error
189//! [`ErrorKind`]: enum@ErrorKind
190//! [`Result`]: type@Result
191//! [`Read`]: std::io::Read
192//! [`SeekFrom`]: enum@SeekFrom
193//! [`Sink`]: https://docs.rs/futures/0.3/futures/sink/trait.Sink.html
194//! [`Stream`]: https://docs.rs/futures/0.3/futures/stream/trait.Stream.html
195//! [`Write`]: std::io::Write
196
197#![cfg_attr(
198 not(all(feature = "rt", feature = "net")),
199 allow(dead_code, unused_imports)
200)]
201
202cfg_io_blocking! {
203 pub(crate) mod blocking;
204}
205
206mod async_buf_read;
207pub use self::async_buf_read::AsyncBufRead;
208
209mod async_read;
210pub use self::async_read::AsyncRead;
211
212mod async_seek;
213pub use self::async_seek::AsyncSeek;
214
215mod async_write;
216pub use self::async_write::AsyncWrite;
217
218mod read_buf;
219pub use self::read_buf::ReadBuf;
220
221// Re-export some types from `std::io` so that users don't have to deal
222// with conflicts when `use`ing `tokio::io` and `std::io`.
223#[doc(no_inline)]
224pub use std::io::{Error, ErrorKind, Result, SeekFrom};
225
226cfg_io_driver_impl! {
227 pub(crate) mod interest;
228 pub(crate) mod ready;
229
230 cfg_net_or_uring! {
231 pub use interest::Interest;
232 pub use ready::Ready;
233 }
234
235 #[cfg_attr(target_os = "wasi", allow(unused_imports))]
236 mod poll_evented;
237
238 #[cfg(not(loom))]
239 #[cfg_attr(target_os = "wasi", allow(unused_imports))]
240 pub(crate) use poll_evented::PollEvented;
241}
242
243// The bsd module can't be build on Windows, so we completely ignore it, even
244// when building documentation.
245#[cfg(unix)]
246cfg_aio! {
247 /// BSD-specific I/O types.
248 pub mod bsd {
249 mod poll_aio;
250
251 pub use poll_aio::{Aio, AioEvent, AioSource};
252 }
253}
254
255cfg_net_unix! {
256 mod async_fd;
257
258 pub mod unix {
259 //! Asynchronous IO structures specific to Unix-like operating systems.
260 pub use super::async_fd::{AsyncFd, AsyncFdTryNewError, AsyncFdReadyGuard, AsyncFdReadyMutGuard, TryIoError};
261 }
262}
263
264cfg_io_std! {
265 mod stdio_common;
266
267 mod stderr;
268 pub use stderr::{stderr, Stderr};
269
270 mod stdin;
271 pub use stdin::{stdin, Stdin};
272
273 mod stdout;
274 pub use stdout::{stdout, Stdout};
275}
276
277cfg_io_util! {
278 mod split;
279 pub use split::{split, ReadHalf, WriteHalf};
280 mod join;
281 pub use join::{join, Join};
282
283 pub(crate) mod seek;
284 pub(crate) mod util;
285 pub use util::{
286 copy, copy_bidirectional, copy_bidirectional_with_sizes, copy_buf, duplex, empty, repeat, sink, simplex, AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt,
287 BufReader, BufStream, BufWriter, Chain, DuplexStream, Empty, Lines, Repeat, Sink, Split, Take, SimplexStream,
288 };
289}
290
291cfg_not_io_util! {
292 cfg_process! {
293 pub(crate) mod util;
294 }
295}
296
297cfg_io_blocking! {
298 /// Types in this module can be mocked out in tests.
299 mod sys {
300 // TODO: don't rename
301 pub(crate) use crate::blocking::spawn_blocking as run;
302 pub(crate) use crate::blocking::JoinHandle as Blocking;
303 }
304}
305
306cfg_io_uring! {
307 pub(crate) mod uring;
308}