]>
Commit | Line | Data |
---|---|---|
5099ac24 FG |
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 | //! | |
fe692bf9 FG |
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`]. | |
5099ac24 | 141 | //! |
fe692bf9 FG |
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. | |
5099ac24 | 147 | //! |
fe692bf9 FG |
148 | //! [tokio-util]: https://docs.rs/tokio-util |
149 | //! [tokio-util::codec]: https://docs.rs/tokio-util/latest/tokio_util/codec/index.html | |
5099ac24 FG |
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 | |
fe692bf9 FG |
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 | |
5099ac24 FG |
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 | |
fe692bf9 FG |
187 | |
188 | #![cfg_attr( | |
189 | not(all(feature = "rt", feature = "net")), | |
190 | allow(dead_code, unused_imports) | |
191 | )] | |
192 | ||
5099ac24 FG |
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! { | |
fe692bf9 FG |
218 | pub(crate) mod interest; |
219 | pub(crate) mod ready; | |
5099ac24 FG |
220 | |
221 | cfg_net! { | |
fe692bf9 FG |
222 | pub use interest::Interest; |
223 | pub use ready::Ready; | |
5099ac24 FG |
224 | } |
225 | ||
fe692bf9 | 226 | #[cfg_attr(tokio_wasi, allow(unused_imports))] |
5099ac24 FG |
227 | mod poll_evented; |
228 | ||
229 | #[cfg(not(loom))] | |
fe692bf9 | 230 | #[cfg_attr(tokio_wasi, allow(unused_imports))] |
5099ac24 FG |
231 | pub(crate) use poll_evented::PollEvented; |
232 | } | |
233 | ||
fe692bf9 FG |
234 | cfg_aio! { |
235 | /// BSD-specific I/O types. | |
236 | pub mod bsd { | |
237 | mod poll_aio; | |
238 | ||
239 | pub use poll_aio::{Aio, AioEvent, AioSource}; | |
240 | } | |
241 | } | |
242 | ||
5099ac24 FG |
243 | cfg_net_unix! { |
244 | mod async_fd; | |
245 | ||
246 | pub mod unix { | |
247 | //! Asynchronous IO structures specific to Unix-like operating systems. | |
248 | pub use super::async_fd::{AsyncFd, AsyncFdReadyGuard, AsyncFdReadyMutGuard, TryIoError}; | |
249 | } | |
250 | } | |
251 | ||
252 | cfg_io_std! { | |
253 | mod stdio_common; | |
254 | ||
255 | mod stderr; | |
256 | pub use stderr::{stderr, Stderr}; | |
257 | ||
258 | mod stdin; | |
259 | pub use stdin::{stdin, Stdin}; | |
260 | ||
261 | mod stdout; | |
262 | pub use stdout::{stdout, Stdout}; | |
263 | } | |
264 | ||
265 | cfg_io_util! { | |
266 | mod split; | |
267 | pub use split::{split, ReadHalf, WriteHalf}; | |
268 | ||
269 | pub(crate) mod seek; | |
270 | pub(crate) mod util; | |
271 | pub use util::{ | |
272 | copy, copy_bidirectional, copy_buf, duplex, empty, repeat, sink, AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt, | |
273 | BufReader, BufStream, BufWriter, DuplexStream, Empty, Lines, Repeat, Sink, Split, Take, | |
274 | }; | |
275 | } | |
276 | ||
277 | cfg_not_io_util! { | |
278 | cfg_process! { | |
279 | pub(crate) mod util; | |
280 | } | |
281 | } | |
282 | ||
283 | cfg_io_blocking! { | |
284 | /// Types in this module can be mocked out in tests. | |
285 | mod sys { | |
286 | // TODO: don't rename | |
287 | pub(crate) use crate::blocking::spawn_blocking as run; | |
288 | pub(crate) use crate::blocking::JoinHandle as Blocking; | |
289 | } | |
290 | } |