• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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