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