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