async_std/io/mod.rs
1//! Traits, helpers, and type definitions for core I/O functionality.
2//!
3//! The `async_std::io` module contains a number of common things you'll need
4//! when doing input and output. The most core part of this module is
5//! the [`Read`] and [`Write`] traits, which provide the
6//! most general interface for reading and writing input and output.
7//!
8//! This module is an async version of [`std::io`].
9//!
10//! [`std::io`]: https://doc.rust-lang.org/std/io/index.html
11//!
12//! # Read and Write
13//!
14//! Because they are traits, [`Read`] and [`Write`] are implemented by a number
15//! of other types, and you can implement them for your types too. As such,
16//! you'll see a few different types of I/O throughout the documentation in
17//! this module: [`File`]s, [`TcpStream`]s, and sometimes even [`Vec<T>`]s. For
18//! example, [`Read`] adds a [`read`][`Read::read`] method, which we can use on
19//! [`File`]s:
20//!
21//! ```no_run
22//! use async_std::fs::File;
23//! use async_std::prelude::*;
24//!
25//! # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
26//! #
27//! let mut f = File::open("foo.txt").await?;
28//! let mut buffer = [0; 10];
29//!
30//! // read up to 10 bytes
31//! let n = f.read(&mut buffer).await?;
32//!
33//! println!("The bytes: {:?}", &buffer[..n]);
34//! #
35//! # Ok(()) }) }
36//! ```
37//!
38//! [`Read`] and [`Write`] are so important, implementors of the two traits have a
39//! nickname: readers and writers. So you'll sometimes see 'a reader' instead
40//! of 'a type that implements the [`Read`] trait'. Much easier!
41//!
42//! ## Seek and BufRead
43//!
44//! Beyond that, there are two important traits that are provided: [`Seek`]
45//! and [`BufRead`]. Both of these build on top of a reader to control
46//! how the reading happens. [`Seek`] lets you control where the next byte is
47//! coming from:
48//!
49//! ```no_run
50//! use async_std::fs::File;
51//! use async_std::io::SeekFrom;
52//! use async_std::prelude::*;
53//!
54//! # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
55//! #
56//! let mut f = File::open("foo.txt").await?;
57//! let mut buffer = [0; 10];
58//!
59//! // skip to the last 10 bytes of the file
60//! f.seek(SeekFrom::End(-10)).await?;
61//!
62//! // read up to 10 bytes
63//! let n = f.read(&mut buffer).await?;
64//!
65//! println!("The bytes: {:?}", &buffer[..n]);
66//! #
67//! # Ok(()) }) }
68//! ```
69//!
70//! [`BufRead`] uses an internal buffer to provide a number of other ways to read, but
71//! to show it off, we'll need to talk about buffers in general. Keep reading!
72//!
73//! ## BufReader and BufWriter
74//!
75//! Byte-based interfaces are unwieldy and can be inefficient, as we'd need to be
76//! making near-constant calls to the operating system. To help with this,
77//! `std::io` comes with two structs, [`BufReader`] and [`BufWriter`], which wrap
78//! readers and writers. The wrapper uses a buffer, reducing the number of
79//! calls and providing nicer methods for accessing exactly what you want.
80//!
81//! For example, [`BufReader`] works with the [`BufRead`] trait to add extra
82//! methods to any reader:
83//!
84//! ```no_run
85//! use async_std::fs::File;
86//! use async_std::io::BufReader;
87//! use async_std::prelude::*;
88//!
89//! # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
90//! #
91//! let f = File::open("foo.txt").await?;
92//! let mut reader = BufReader::new(f);
93//! let mut buffer = String::new();
94//!
95//! // read a line into buffer
96//! reader.read_line(&mut buffer).await?;
97//!
98//! println!("{}", buffer);
99//! #
100//! # Ok(()) }) }
101//! ```
102//!
103//! [`BufWriter`] doesn't add any new ways of writing; it just buffers every call
104//! to [`write`][`Write::write`]:
105//!
106//! ```no_run
107//! use async_std::fs::File;
108//! use async_std::io::prelude::*;
109//! use async_std::io::BufWriter;
110//!
111//! # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
112//! #
113//! let f = File::create("foo.txt").await?;
114//! {
115//! let mut writer = BufWriter::new(f);
116//!
117//! // write a byte to the buffer
118//! writer.write(&[42]).await?;
119//! } // the buffer is flushed once writer goes out of scope
120//! //
121//! #
122//! # Ok(()) }) }
123//! ```
124//!
125//! ## Standard input and output
126//!
127//! A very common source of input is standard input:
128//!
129//! ```no_run
130//! use async_std::io;
131//!
132//! # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
133//! #
134//! let mut input = String::new();
135//!
136//! io::stdin().read_line(&mut input).await?;
137//!
138//! println!("You typed: {}", input.trim());
139//! #
140//! # Ok(()) }) }
141//! ```
142//!
143//! Note that you cannot use the [`?` operator] in functions that do not return
144//! a [`Result<T, E>`][`Result`]. Instead, you can call [`.unwrap()`]
145//! or `match` on the return value to catch any possible errors:
146//!
147//! ```no_run
148//! use async_std::io;
149//!
150//! # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
151//! #
152//! let mut input = String::new();
153//!
154//! io::stdin().read_line(&mut input).await.unwrap();
155//! #
156//! # Ok(()) }) }
157//! ```
158//!
159//! And a very common source of output is standard output:
160//!
161//! ```no_run
162//! use async_std::io;
163//! use async_std::io::prelude::*;
164//!
165//! # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
166//! #
167//! io::stdout().write(&[42]).await?;
168//! #
169//! # Ok(()) }) }
170//! ```
171//!
172//! Of course, using [`io::stdout`] directly is less common than something like
173//! [`println!`].
174//!
175//! ## Iterator types
176//!
177//! A large number of the structures provided by `std::io` are for various
178//! ways of iterating over I/O. For example, [`Lines`] is used to split over
179//! lines:
180//!
181//! ```no_run
182//! use async_std::fs::File;
183//! use async_std::io::BufReader;
184//! use async_std::prelude::*;
185//!
186//! # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
187//! #
188//! let f = File::open("foo.txt").await?;
189//! let reader = BufReader::new(f);
190//!
191//! let mut lines = reader.lines();
192//! while let Some(line) = lines.next().await {
193//! println!("{}", line?);
194//! }
195//! #
196//! # Ok(()) }) }
197//! ```
198//!
199//! ## Functions
200//!
201//! There are a number of [functions][functions-list] that offer access to various
202//! features. For example, we can use three of these functions to copy everything
203//! from standard input to standard output:
204//!
205//! ```no_run
206//! use async_std::io;
207//!
208//! # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
209//! #
210//! io::copy(&mut io::stdin(), &mut io::stdout()).await?;
211//! #
212//! # Ok(()) }) }
213//! ```
214//!
215//! [functions-list]: #functions-1
216//!
217//! ## io::Result
218//!
219//! Last, but certainly not least, is [`io::Result`]. This type is used
220//! as the return type of many `std::io` functions that can cause an error, and
221//! can be returned from your own functions as well. Many of the examples in this
222//! module use the [`?` operator]:
223//!
224//! ```
225//! #![allow(dead_code)]
226//! use async_std::io;
227//!
228//! async fn read_input() -> io::Result<()> {
229//! let mut input = String::new();
230//!
231//! io::stdin().read_line(&mut input).await?;
232//!
233//! println!("You typed: {}", input.trim());
234//!
235//! Ok(())
236//! }
237//! ```
238//!
239//! The return type of `read_input`, [`io::Result<()>`][`io::Result`], is a very
240//! common type for functions which don't have a 'real' return value, but do want to
241//! return errors if they happen. In this case, the only purpose of this function is
242//! to read the line and print it, so we use `()`.
243//!
244//! ## Platform-specific behavior
245//!
246//! Many I/O functions throughout the standard library are documented to indicate
247//! what various library or syscalls they are delegated to. This is done to help
248//! applications both understand what's happening under the hood as well as investigate
249//! any possibly unclear semantics. Note, however, that this is informative, not a binding
250//! contract. The implementation of many of these functions are subject to change over
251//! time and may call fewer or more syscalls/library functions.
252//!
253//! [`Read`]: trait.Read.html
254//! [`Write`]: trait.Write.html
255//! [`Seek`]: trait.Seek.html
256//! [`BufRead`]: trait.BufRead.html
257//! [`File`]: ../fs/struct.File.html
258//! [`TcpStream`]: ../net/struct.TcpStream.html
259//! [`Vec<T>`]: ../vec/struct.Vec.html
260//! [`BufReader`]: struct.BufReader.html
261//! [`BufWriter`]: struct.BufWriter.html
262//! [`Write::write`]: trait.Write.html#tymethod.write
263//! [`io::stdout`]: fn.stdout.html
264//! [`println!`]: ../macro.println.html
265//! [`Lines`]: struct.Lines.html
266//! [`io::Result`]: type.Result.html
267//! [`?` operator]: https://doc.rust-lang.org/stable/book/appendix-02-operators.html
268//! [`Read::read`]: trait.Read.html#tymethod.read
269//! [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
270//! [`.unwrap()`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap
271
272const DEFAULT_BUF_SIZE: usize = 8 * 1024;
273
274cfg_std! {
275 #[doc(inline)]
276 pub use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom};
277
278 pub use buf_read::*;
279 pub use buf_reader::BufReader;
280 pub use buf_writer::{BufWriter, IntoInnerError};
281 pub use copy::copy;
282 pub use cursor::Cursor;
283 pub use empty::{empty, Empty};
284 pub use read::*;
285 pub use repeat::{repeat, Repeat};
286 pub use seek::*;
287 pub use sink::{sink, Sink};
288 pub use write::*;
289
290 pub mod prelude;
291
292 pub(crate) mod buf_read;
293 pub(crate) mod read;
294 pub(crate) mod seek;
295 pub(crate) mod write;
296 pub(crate) mod utils;
297
298 mod buf_reader;
299 mod buf_writer;
300 mod copy;
301 mod cursor;
302 mod empty;
303 mod repeat;
304 mod sink;
305}
306
307cfg_default! {
308 // For use in the print macros.
309 #[doc(hidden)]
310 #[cfg(not(target_os = "unknown"))]
311 pub use stdio::{_eprint, _print};
312
313 #[cfg(not(target_os = "unknown"))]
314 pub use stderr::{stderr, Stderr};
315 #[cfg(not(target_os = "unknown"))]
316 pub use stdin::{stdin, Stdin};
317 #[cfg(not(target_os = "unknown"))]
318 pub use stdout::{stdout, Stdout};
319 pub use timeout::timeout;
320
321 mod timeout;
322 #[cfg(not(target_os = "unknown"))]
323 mod stderr;
324 #[cfg(not(target_os = "unknown"))]
325 mod stdin;
326 #[cfg(not(target_os = "unknown"))]
327 mod stdio;
328 #[cfg(not(target_os = "unknown"))]
329 mod stdout;
330}