about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSteve Klabnik <steve@steveklabnik.com>2015-07-20 18:07:35 -0400
committerSteve Klabnik <steve@steveklabnik.com>2015-07-20 18:07:35 -0400
commitfa28192312f2b22e411fc19db78893acf52fa7cf (patch)
treef87289fe0584e47cab778e01adc47f2537829f1e
parent4e51763e6428580f2b3275cd7076492376801a1e (diff)
downloadrust-fa28192312f2b22e411fc19db78893acf52fa7cf.tar.gz
rust-fa28192312f2b22e411fc19db78893acf52fa7cf.zip
Write better docs for std::io
This is the landing page for all of io, so we should have more than just
a sentence here.
-rw-r--r--src/libstd/io/mod.rs229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 24474731031..3016cfa8fe5 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -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")]