Skip to content

Write better docs for std::io #27171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 21, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 229 additions & 0 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,235 @@
// except according to those terms.

//! Traits, helpers, and type definitions for core I/O functionality.
//!
//! The `std::io` module contains a number of common things you'll need
//! when doing input and output. The most core part of this module is
//! the [`Read`][read] and [`Write`][write] traits, which provide the
//! most general interface for reading and writing input and output.
//!
//! [read]: trait.Read.html
//! [write]: trait.Write.html
//!
//! # Read and Write
//!
//! Because they are traits, they're implemented by a number of other types,
//! and you can implement them for your types too. As such, you'll see a
//! few different types of I/O throughout the documentation in this module:
//! `File`s, `TcpStream`s, and somtimes even `Vec<T>`s. For example, `Read`
//! adds a `read()` method, which we can use on `File`s:
//!
//! ```
//! use std::io;
//! use std::io::prelude::*;
//! use std::fs::File;
//!
//! # fn foo() -> io::Result<()> {
//! let mut f = try!(File::open("foo.txt"));
//! let mut buffer = [0; 10];
//!
//! // read up to 10 bytes
//! try!(f.read(&mut buffer));
//!
//! println!("The bytes: {:?}", buffer);
//! # Ok(())
//! # }
//! ```
//!
//! `Read` and `Write` are so important, implementors of the two traits have a
//! nickname: readers and writers. So you'll sometimes see 'a reader' instead
//! of 'a type that implements the `Read` trait'. Much easier!
//!
//! ## Seek and BufRead
//!
//! Beyond that, there are two important traits that are provided: [`Seek`][seek]
//! and [`BufRead`][bufread]. Both of these build on top of a reader to control
//! how the reading happens. `Seek` lets you control where the next byte is
//! coming from:
//!
//! ```
//! use std::io;
//! use std::io::prelude::*;
//! use std::io::SeekFrom;
//! use std::fs::File;
//!
//! # fn foo() -> io::Result<()> {
//! let mut f = try!(File::open("foo.txt"));
//! let mut buffer = [0; 10];
//!
//! // skip to the last 10 bytes of the file
//! try!(f.seek(SeekFrom::End(-10)));
//!
//! // read up to 10 bytes
//! try!(f.read(&mut buffer));
//!
//! println!("The bytes: {:?}", buffer);
//! # Ok(())
//! # }
//! ```
//!
//! [seek]: trait.Seek.html
//! [bufread]: trait.BufRead.html
//!
//! `BufRead` uses an internal buffer to provide a number of other ways to read, but
//! to show it off, we'll need to talk about buffers in general. Keep reading!
//!
//! ## BufReader and BufWriter
//!
//! Byte-based interfaces are unwieldy and can be inefficient, as we'd need to be
//! making near-constant calls to the operating system. To help with this,
//! `std::io` comes with two structs, `BufReader` and `BufWriter`, which wrap
//! readers and writers. The wrapper uses a buffer, reducing the number of
//! calls and providing nicer methods for accessing exactly what you want.
//!
//! For example, `BufReader` works with the `BufRead` trait to add extra
//! methods to any reader:
//!
//! ```
//! use std::io;
//! use std::io::prelude::*;
//! use std::io::BufReader;
//! use std::fs::File;
//!
//! # fn foo() -> io::Result<()> {
//! let f = try!(File::open("foo.txt"));
//! let mut reader = BufReader::new(f);
//! let mut buffer = String::new();
//!
//! // read a line into buffer
//! try!(reader.read_line(&mut buffer));
//!
//! println!("{}", buffer);
//! # Ok(())
//! # }
//! ```
//!
//! `BufWriter` doesn't add any new ways of writing, it just buffers every call
//! to [`write()`][write]:
//!
//! ```
//! use std::io;
//! use std::io::prelude::*;
//! use std::io::BufWriter;
//! use std::fs::File;
//!
//! # fn foo() -> io::Result<()> {
//! let f = try!(File::create("foo.txt"));
//! {
//! let mut writer = BufWriter::new(f);
//!
//! // write a byte to the buffer
//! try!(writer.write(&[42]));
//!
//! } // the buffer is flushed once writer goes out of scope
//!
//! # Ok(())
//! # }
//! ```
//!
//! [write]: trait.Write.html#tymethod.write
//!
//! ## Standard input and output
//!
//! A very common source of input is standard input:
//!
//! ```
//! use std::io;
//!
//! # fn foo() -> io::Result<()> {
//! let mut input = String::new();
//!
//! try!(io::stdin().read_line(&mut input));
//!
//! println!("You typed: {}", input.trim());
//! # Ok(())
//! # }
//! ```
//!
//! And a very common source of output is standard output:
//!
//! ```
//! use std::io;
//! use std::io::prelude::*;
//!
//! # fn foo() -> io::Result<()> {
//! try!(io::stdout().write(&[42]));
//! # Ok(())
//! # }
//! ```
//!
//! Of course, using `io::stdout()` directly is less comon than something like
//! `println!`.
//!
//! ## Iterator types
//!
//! A large number of the structures provided by `std::io` are for various
//! ways of iterating over I/O. For example, `Lines` is used to split over
//! lines:
//!
//! ```
//! use std::io;
//! use std::io::prelude::*;
//! use std::io::BufReader;
//! use std::fs::File;
//!
//! # fn foo() -> io::Result<()> {
//! let f = try!(File::open("foo.txt"));
//! let mut reader = BufReader::new(f);
//!
//! for line in reader.lines() {
//! let line = try!(line);
//! println!("{}", line);
//! }
//!
//! # Ok(())
//! # }
//! ```
//!
//! ## Functions
//!
//! There are a number of [functions][functions] that offer access to various
//! features. For example, we can use three of these functions to copy everything
//! from standard input to standard output:
//!
//! ```
//! use std::io;
//!
//! # fn foo() -> io::Result<()> {
//! try!(io::copy(&mut io::stdin(), &mut io::stdout()));
//! # Ok(())
//! # }
//! ```
//!
//! [functions]: #functions
//!
//! ## io::Result
//!
//! Last, but certainly not least, is [`io::Result`][result]. This type is used
//! as the return type of many `std::io` functions that can cause an error, and
//! can be returned from your own functions as well. Many of the examples in this
//! module use the [`try!`][try] macro:
//!
//! ```
//! use std::io;
//!
//! fn read_input() -> io::Result<()> {
//! let mut input = String::new();
//!
//! try!(io::stdin().read_line(&mut input));
//!
//! println!("You typed: {}", input.trim());
//!
//! Ok(())
//! }
//! ```
//!
//! The return type of `read_input()`, `io::Result<()>`, is a very common type
//! for functions which don't have a 'real' return value, but do want to return
//! errors if they happen. In this case, the only purpose of this function is
//! to read the line and print it, so we use use `()`.
//!
//! [result]: type.Result.html
//! [try]: macro.try!.html

#![stable(feature = "rust1", since = "1.0.0")]

Expand Down