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