| 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 | |
| 272 | const DEFAULT_BUF_SIZE: usize = 8 * 1024; |
| 273 | |
| 274 | cfg_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 | |
| 307 | cfg_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 | } |
| 331 | |