|
47 | 47 | //! coming from:
|
48 | 48 | //!
|
49 | 49 | //! ```no_run
|
50 |
| -//! use async_std::prelude::*; |
| 50 | +//! use async_std::io::prelude::*; |
51 | 51 | //! use async_std::io::SeekFrom;
|
52 | 52 | //! use async_std::fs::File;
|
53 | 53 | //!
|
|
69 | 69 | //!
|
70 | 70 | //! [`BufRead`] uses an internal buffer to provide a number of other ways to read, but
|
71 | 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::io::prelude::*; |
| 86 | +//! use async_std::io::BufReader; |
| 87 | +//! use async_std::fs::File; |
| 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::io::prelude::*; |
| 108 | +//! use async_std::io::BufWriter; |
| 109 | +//! use async_std::fs::File; |
| 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 | +//! |
| 120 | +//! } // the buffer is flushed once writer goes out of scope |
| 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::prelude::*; |
| 183 | +//! use async_std::io::BufReader; |
| 184 | +//! use async_std::fs::File; |
| 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 |
72 | 271 |
|
73 | 272 | #[doc(inline)]
|
74 | 273 | pub use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Result, SeekFrom};
|
|
0 commit comments