Skip to content

Commit 90a3692

Browse files
committed
Auto merge of #27171 - steveklabnik:doc_std_io, r=brson
This is the landing page for all of io, so we should have more than just a sentence here. r? @alexcrichton and I know @brson has been caring a lot about landing page style docs lately.
2 parents fec23d9 + fa28192 commit 90a3692

File tree

1 file changed

+229
-0
lines changed

1 file changed

+229
-0
lines changed

src/libstd/io/mod.rs

+229
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,235 @@
99
// except according to those terms.
1010

1111
//! 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
12241
13242
#![stable(feature = "rust1", since = "1.0.0")]
14243

0 commit comments

Comments
 (0)