|
9 | 9 | // except according to those terms.
|
10 | 10 |
|
11 | 11 | //! Traits, helpers, and type definitions for core I/O functionality.
|
| 12 | +//! |
| 13 | +//! The `std::io` module contains a number of common things you'll need |
| 14 | +//! when doing input and output. The most core part of this module is |
| 15 | +//! the [`Read`][read] and [`Write`][write] traits, which provide the |
| 16 | +//! most general interface for reading and writing input and output. |
| 17 | +//! |
| 18 | +//! [read]: trait.Read.html |
| 19 | +//! [write]: trait.Write.html |
| 20 | +//! |
| 21 | +//! # Read and Write |
| 22 | +//! |
| 23 | +//! Because they are traits, they're implemented by a number of other types, |
| 24 | +//! and you can implement them for your types too. As such, you'll see a |
| 25 | +//! few different types of I/O throughout the documentation in this module: |
| 26 | +//! `File`s, `TcpStream`s, and somtimes even `Vec<T>`s. For example, `Read` |
| 27 | +//! adds a `read()` method, which we can use on `File`s: |
| 28 | +//! |
| 29 | +//! ``` |
| 30 | +//! use std::io; |
| 31 | +//! use std::io::prelude::*; |
| 32 | +//! use std::fs::File; |
| 33 | +//! |
| 34 | +//! # fn foo() -> io::Result<()> { |
| 35 | +//! let mut f = try!(File::open("foo.txt")); |
| 36 | +//! let mut buffer = [0; 10]; |
| 37 | +//! |
| 38 | +//! // read up to 10 bytes |
| 39 | +//! try!(f.read(&mut buffer)); |
| 40 | +//! |
| 41 | +//! println!("The bytes: {:?}", buffer); |
| 42 | +//! # Ok(()) |
| 43 | +//! # } |
| 44 | +//! ``` |
| 45 | +//! |
| 46 | +//! `Read` and `Write` are so important, implementors of the two traits have a |
| 47 | +//! nickname: readers and writers. So you'll sometimes see 'a reader' instead |
| 48 | +//! of 'a type that implements the `Read` trait'. Much easier! |
| 49 | +//! |
| 50 | +//! ## Seek and BufRead |
| 51 | +//! |
| 52 | +//! Beyond that, there are two important traits that are provided: [`Seek`][seek] |
| 53 | +//! and [`BufRead`][bufread]. Both of these build on top of a reader to control |
| 54 | +//! how the reading happens. `Seek` lets you control where the next byte is |
| 55 | +//! coming from: |
| 56 | +//! |
| 57 | +//! ``` |
| 58 | +//! use std::io; |
| 59 | +//! use std::io::prelude::*; |
| 60 | +//! use std::io::SeekFrom; |
| 61 | +//! use std::fs::File; |
| 62 | +//! |
| 63 | +//! # fn foo() -> io::Result<()> { |
| 64 | +//! let mut f = try!(File::open("foo.txt")); |
| 65 | +//! let mut buffer = [0; 10]; |
| 66 | +//! |
| 67 | +//! // skip to the last 10 bytes of the file |
| 68 | +//! try!(f.seek(SeekFrom::End(-10))); |
| 69 | +//! |
| 70 | +//! // read up to 10 bytes |
| 71 | +//! try!(f.read(&mut buffer)); |
| 72 | +//! |
| 73 | +//! println!("The bytes: {:?}", buffer); |
| 74 | +//! # Ok(()) |
| 75 | +//! # } |
| 76 | +//! ``` |
| 77 | +//! |
| 78 | +//! [seek]: trait.Seek.html |
| 79 | +//! [bufread]: trait.BufRead.html |
| 80 | +//! |
| 81 | +//! `BufRead` uses an internal buffer to provide a number of other ways to read, but |
| 82 | +//! to show it off, we'll need to talk about buffers in general. Keep reading! |
| 83 | +//! |
| 84 | +//! ## BufReader and BufWriter |
| 85 | +//! |
| 86 | +//! Byte-based interfaces are unwieldy and can be inefficient, as we'd need to be |
| 87 | +//! making near-constant calls to the operating system. To help with this, |
| 88 | +//! `std::io` comes with two structs, `BufReader` and `BufWriter`, which wrap |
| 89 | +//! readers and writers. The wrapper uses a buffer, reducing the number of |
| 90 | +//! calls and providing nicer methods for accessing exactly what you want. |
| 91 | +//! |
| 92 | +//! For example, `BufReader` works with the `BufRead` trait to add extra |
| 93 | +//! methods to any reader: |
| 94 | +//! |
| 95 | +//! ``` |
| 96 | +//! use std::io; |
| 97 | +//! use std::io::prelude::*; |
| 98 | +//! use std::io::BufReader; |
| 99 | +//! use std::fs::File; |
| 100 | +//! |
| 101 | +//! # fn foo() -> io::Result<()> { |
| 102 | +//! let f = try!(File::open("foo.txt")); |
| 103 | +//! let mut reader = BufReader::new(f); |
| 104 | +//! let mut buffer = String::new(); |
| 105 | +//! |
| 106 | +//! // read a line into buffer |
| 107 | +//! try!(reader.read_line(&mut buffer)); |
| 108 | +//! |
| 109 | +//! println!("{}", buffer); |
| 110 | +//! # Ok(()) |
| 111 | +//! # } |
| 112 | +//! ``` |
| 113 | +//! |
| 114 | +//! `BufWriter` doesn't add any new ways of writing, it just buffers every call |
| 115 | +//! to [`write()`][write]: |
| 116 | +//! |
| 117 | +//! ``` |
| 118 | +//! use std::io; |
| 119 | +//! use std::io::prelude::*; |
| 120 | +//! use std::io::BufWriter; |
| 121 | +//! use std::fs::File; |
| 122 | +//! |
| 123 | +//! # fn foo() -> io::Result<()> { |
| 124 | +//! let f = try!(File::create("foo.txt")); |
| 125 | +//! { |
| 126 | +//! let mut writer = BufWriter::new(f); |
| 127 | +//! |
| 128 | +//! // write a byte to the buffer |
| 129 | +//! try!(writer.write(&[42])); |
| 130 | +//! |
| 131 | +//! } // the buffer is flushed once writer goes out of scope |
| 132 | +//! |
| 133 | +//! # Ok(()) |
| 134 | +//! # } |
| 135 | +//! ``` |
| 136 | +//! |
| 137 | +//! [write]: trait.Write.html#tymethod.write |
| 138 | +//! |
| 139 | +//! ## Standard input and output |
| 140 | +//! |
| 141 | +//! A very common source of input is standard input: |
| 142 | +//! |
| 143 | +//! ``` |
| 144 | +//! use std::io; |
| 145 | +//! |
| 146 | +//! # fn foo() -> io::Result<()> { |
| 147 | +//! let mut input = String::new(); |
| 148 | +//! |
| 149 | +//! try!(io::stdin().read_line(&mut input)); |
| 150 | +//! |
| 151 | +//! println!("You typed: {}", input.trim()); |
| 152 | +//! # Ok(()) |
| 153 | +//! # } |
| 154 | +//! ``` |
| 155 | +//! |
| 156 | +//! And a very common source of output is standard output: |
| 157 | +//! |
| 158 | +//! ``` |
| 159 | +//! use std::io; |
| 160 | +//! use std::io::prelude::*; |
| 161 | +//! |
| 162 | +//! # fn foo() -> io::Result<()> { |
| 163 | +//! try!(io::stdout().write(&[42])); |
| 164 | +//! # Ok(()) |
| 165 | +//! # } |
| 166 | +//! ``` |
| 167 | +//! |
| 168 | +//! Of course, using `io::stdout()` directly is less comon than something like |
| 169 | +//! `println!`. |
| 170 | +//! |
| 171 | +//! ## Iterator types |
| 172 | +//! |
| 173 | +//! A large number of the structures provided by `std::io` are for various |
| 174 | +//! ways of iterating over I/O. For example, `Lines` is used to split over |
| 175 | +//! lines: |
| 176 | +//! |
| 177 | +//! ``` |
| 178 | +//! use std::io; |
| 179 | +//! use std::io::prelude::*; |
| 180 | +//! use std::io::BufReader; |
| 181 | +//! use std::fs::File; |
| 182 | +//! |
| 183 | +//! # fn foo() -> io::Result<()> { |
| 184 | +//! let f = try!(File::open("foo.txt")); |
| 185 | +//! let mut reader = BufReader::new(f); |
| 186 | +//! |
| 187 | +//! for line in reader.lines() { |
| 188 | +//! let line = try!(line); |
| 189 | +//! println!("{}", line); |
| 190 | +//! } |
| 191 | +//! |
| 192 | +//! # Ok(()) |
| 193 | +//! # } |
| 194 | +//! ``` |
| 195 | +//! |
| 196 | +//! ## Functions |
| 197 | +//! |
| 198 | +//! There are a number of [functions][functions] that offer access to various |
| 199 | +//! features. For example, we can use three of these functions to copy everything |
| 200 | +//! from standard input to standard output: |
| 201 | +//! |
| 202 | +//! ``` |
| 203 | +//! use std::io; |
| 204 | +//! |
| 205 | +//! # fn foo() -> io::Result<()> { |
| 206 | +//! try!(io::copy(&mut io::stdin(), &mut io::stdout())); |
| 207 | +//! # Ok(()) |
| 208 | +//! # } |
| 209 | +//! ``` |
| 210 | +//! |
| 211 | +//! [functions]: #functions |
| 212 | +//! |
| 213 | +//! ## io::Result |
| 214 | +//! |
| 215 | +//! Last, but certainly not least, is [`io::Result`][result]. This type is used |
| 216 | +//! as the return type of many `std::io` functions that can cause an error, and |
| 217 | +//! can be returned from your own functions as well. Many of the examples in this |
| 218 | +//! module use the [`try!`][try] macro: |
| 219 | +//! |
| 220 | +//! ``` |
| 221 | +//! use std::io; |
| 222 | +//! |
| 223 | +//! fn read_input() -> io::Result<()> { |
| 224 | +//! let mut input = String::new(); |
| 225 | +//! |
| 226 | +//! try!(io::stdin().read_line(&mut input)); |
| 227 | +//! |
| 228 | +//! println!("You typed: {}", input.trim()); |
| 229 | +//! |
| 230 | +//! Ok(()) |
| 231 | +//! } |
| 232 | +//! ``` |
| 233 | +//! |
| 234 | +//! The return type of `read_input()`, `io::Result<()>`, is a very common type |
| 235 | +//! for functions which don't have a 'real' return value, but do want to return |
| 236 | +//! errors if they happen. In this case, the only purpose of this function is |
| 237 | +//! to read the line and print it, so we use use `()`. |
| 238 | +//! |
| 239 | +//! [result]: type.Result.html |
| 240 | +//! [try]: macro.try!.html |
12 | 241 |
|
13 | 242 | #![stable(feature = "rust1", since = "1.0.0")]
|
14 | 243 |
|
|
0 commit comments