Skip to content

Commit 2074b19

Browse files
committed
More docs for std::io::BufRead
1 parent e4e9319 commit 2074b19

File tree

1 file changed

+186
-32
lines changed

1 file changed

+186
-32
lines changed

src/libstd/io/mod.rs

Lines changed: 186 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -505,59 +505,136 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
505505
}
506506
}
507507

508-
/// A `BufRead` is a type of reader which has some form of internal buffering to
509-
/// allow certain kinds of reading operations to be more optimized than others.
508+
/// A `BufRead` is a type of `Read`er which has an internal buffer, allowing it
509+
/// to perform extra ways of reading.
510510
///
511-
/// This type extends the `Read` trait with a few methods that are not
512-
/// possible to reasonably implement with purely a read interface.
511+
/// For example, reading line-by-line requires using a buffer, so if you want
512+
/// to read by line, you'll need `BufRead`, which includes a
513+
/// [`read_line()`][readline] method as well as a [`lines()`][lines] iterator.
514+
///
515+
/// [readline]: #method.read_line
516+
/// [lines]: #method.lines
517+
///
518+
/// # Examples
519+
///
520+
/// A locked standard input implements `BufRead`:
521+
///
522+
/// ```
523+
/// use std::io;
524+
/// use std::io::BufRead;
525+
///
526+
/// let stdin = io::stdin();
527+
/// for line in stdin.lock().lines() {
528+
/// println!("{}", line.unwrap());
529+
/// }
530+
/// ```
531+
///
532+
/// If you have something that implements `Read`, you can use the [`BufReader`
533+
/// type][bufreader] to turn it into a `BufRead`.
534+
///
535+
/// For example, [`File`][file] implements `Read`, but not `BufRead`.
536+
/// `BufReader` to the rescue!
537+
///
538+
/// [bufreader]: struct.BufReader.html
539+
/// [file]: ../fs/struct.File.html
540+
///
541+
/// ```
542+
/// use std::io;
543+
/// use std::fs::File;
544+
/// use std::io::BufRead;
545+
/// use std::io::BufReader;
546+
///
547+
/// # fn foo() -> io::Result<()> {
548+
/// let f = try!(File::open("foo.txt"));
549+
/// let f = BufReader::new(f);
550+
///
551+
/// for line in f.lines() {
552+
/// println!("{}", line.unwrap());
553+
/// }
554+
///
555+
/// # Ok(())
556+
/// # }
557+
/// ```
513558
///
514-
/// You can use the [`BufReader` wrapper type](struct.BufReader.html) to turn any
515-
/// reader into a buffered reader.
516559
#[stable(feature = "rust1", since = "1.0.0")]
517560
pub trait BufRead: Read {
518561
/// Fills the internal buffer of this object, returning the buffer contents.
519562
///
520-
/// None of the contents will be "read" in the sense that later calling
521-
/// `read` may return the same contents.
563+
/// This function is a lower-level call. It needs to be paired with the
564+
/// [`consume`][consume] method to function properly. When calling this
565+
/// method, none of the contents will be "read" in the sense that later
566+
/// calling `read` may return the same contents. As such, `consume` must be
567+
/// called with the number of bytes that are consumed from this buffer to
568+
/// ensure that the bytes are never returned twice.
522569
///
523-
/// The `consume` function must be called with the number of bytes that are
524-
/// consumed from this buffer returned to ensure that the bytes are never
525-
/// returned twice.
570+
/// [consume]: #tymethod.consume
526571
///
527572
/// An empty buffer returned indicates that the stream has reached EOF.
528573
///
529574
/// # Errors
530575
///
531576
/// This function will return an I/O error if the underlying reader was
532577
/// read, but returned an error.
578+
///
579+
/// # Examples
580+
///
581+
/// A locked standard input implements `BufRead`:
582+
///
583+
/// ```
584+
/// use std::io;
585+
/// use std::io::prelude::*;
586+
///
587+
/// let stdin = io::stdin();
588+
/// let mut stdin = stdin.lock();
589+
///
590+
/// // we can't have two `&mut` references to `stdin`, so use a block
591+
/// // to end the borrow early.
592+
/// let length = {
593+
/// let buffer = stdin.fill_buf().unwrap();
594+
///
595+
/// // work with buffer
596+
/// println!("{:?}", buffer);
597+
///
598+
/// buffer.len()
599+
/// };
600+
///
601+
/// // ensure the bytes we worked with aren't returned again later
602+
/// stdin.consume(length);
603+
/// ```
533604
#[stable(feature = "rust1", since = "1.0.0")]
534605
fn fill_buf(&mut self) -> Result<&[u8]>;
535606

536607
/// Tells this buffer that `amt` bytes have been consumed from the buffer,
537608
/// so they should no longer be returned in calls to `read`.
538609
///
539-
/// This function does not perform any I/O, it simply informs this object
540-
/// that some amount of its buffer, returned from `fill_buf`, has been
541-
/// consumed and should no longer be returned.
610+
/// This function is a lower-level call. It needs to be paired with the
611+
/// [`fill_buf`][fillbuf] method to function properly. This function does
612+
/// not perform any I/O, it simply informs this object that some amount of
613+
/// its buffer, returned from `fill_buf`, has been consumed and should no
614+
/// longer be returned. As such, this function may do odd things if
615+
/// `fill_buf` isn't called before calling it.
616+
///
617+
/// [fillbuf]: #tymethod.fill_buff
618+
///
619+
/// The `amt` must be `<=` the number of bytes in the buffer returned by
620+
/// `fill_buf`.
542621
///
543-
/// This function is used to tell the buffer how many bytes you've consumed
544-
/// from the return value of `fill_buf`, and so may do odd things if
545-
/// `fill_buf` isn't called before calling this.
622+
/// # Examples
546623
///
547-
/// The `amt` must be `<=` the number of bytes in the buffer returned by `fill_buf`.
624+
/// Since `consume()` is meant to be used with [`fill_buf()`][fillbuf],
625+
/// that method's example includes an example of `consume()`.
548626
#[stable(feature = "rust1", since = "1.0.0")]
549627
fn consume(&mut self, amt: usize);
550628

551-
/// Read all bytes until the delimiter `byte` is reached.
629+
/// Read all bytes into `buf` until the delimiter `byte` is reached.
552630
///
553-
/// This function will continue to read (and buffer) bytes from the
554-
/// underlying stream until the delimiter or EOF is found. Once found, all
555-
/// bytes up to, and including, the delimiter (if found) will be appended to
556-
/// `buf`.
631+
/// This function will read bytes from the underlying stream until the
632+
/// delimiter or EOF is found. Once found, all bytes up to, and including,
633+
/// the delimiter (if found) will be appended to `buf`.
557634
///
558-
/// If this buffered reader is currently at EOF, then this function will not
559-
/// place any more bytes into `buf` and will return `Ok(n)` where `n` is the
560-
/// number of bytes which were read.
635+
/// If this reader is currently at EOF then this function will not modify
636+
/// `buf` and will return `Ok(n)` where `n` is the number of bytes which
637+
/// were read.
561638
///
562639
/// # Errors
563640
///
@@ -566,18 +643,39 @@ pub trait BufRead: Read {
566643
///
567644
/// If an I/O error is encountered then all bytes read so far will be
568645
/// present in `buf` and its length will have been adjusted appropriately.
646+
///
647+
/// # Examples
648+
///
649+
/// A locked standard input implements `BufRead`. In this example, we'll
650+
/// read from standard input until we see an `a` byte.
651+
///
652+
/// ```
653+
/// use std::io;
654+
/// use std::io::prelude::*;
655+
///
656+
/// fn foo() -> io::Result<()> {
657+
/// let stdin = io::stdin();
658+
/// let mut stdin = stdin.lock();
659+
/// let mut buffer = Vec::new();
660+
///
661+
/// try!(stdin.read_until(b'a', &mut buffer));
662+
///
663+
/// println!("{:?}", buffer);
664+
/// # Ok(())
665+
/// # }
666+
/// ```
569667
#[stable(feature = "rust1", since = "1.0.0")]
570668
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
571669
read_until(self, byte, buf)
572670
}
573671

574-
/// Read all bytes until a newline (the 0xA byte) is reached, and
575-
/// append them to the provided buffer.
672+
/// Read all bytes until a newline (the 0xA byte) is reached, and append
673+
/// them to the provided buffer.
576674
///
577-
/// This function will continue to read (and buffer) bytes from the
578-
/// underlying stream until the newline delimiter (the 0xA byte) or EOF is
579-
/// found. Once found, all bytes up to, and including, the delimiter (if
580-
/// found) will be appended to `buf`.
675+
/// This function will read bytes from the underlying stream until the
676+
/// newline delimiter (the 0xA byte) or EOF is found. Once found, all bytes
677+
/// up to, and including, the delimiter (if found) will be appended to
678+
/// `buf`.
581679
///
582680
/// If this reader is currently at EOF then this function will not modify
583681
/// `buf` and will return `Ok(n)` where `n` is the number of bytes which
@@ -589,6 +687,31 @@ pub trait BufRead: Read {
589687
/// return an error if the read bytes are not valid UTF-8. If an I/O error
590688
/// is encountered then `buf` may contain some bytes already read in the
591689
/// event that all data read so far was valid UTF-8.
690+
///
691+
/// # Examples
692+
///
693+
/// A locked standard input implements `BufRead`. In this example, we'll
694+
/// read all of the lines from standard input. If we were to do this in
695+
/// an actual project, the [`lines()`][lines] method would be easier, of
696+
/// course.
697+
///
698+
/// [lines]: #method.lines
699+
///
700+
/// ```
701+
/// use std::io;
702+
/// use std::io::prelude::*;
703+
///
704+
/// let stdin = io::stdin();
705+
/// let mut stdin = stdin.lock();
706+
/// let mut buffer = String::new();
707+
///
708+
/// while stdin.read_line(&mut buffer).unwrap() > 0 {
709+
/// // work with buffer
710+
/// println!("{:?}", buffer);
711+
///
712+
/// buffer.clear();
713+
/// }
714+
/// ```
592715
#[stable(feature = "rust1", since = "1.0.0")]
593716
fn read_line(&mut self, buf: &mut String) -> Result<usize> {
594717
// Note that we are not calling the `.read_until` method here, but
@@ -606,6 +729,22 @@ pub trait BufRead: Read {
606729
///
607730
/// This function will yield errors whenever `read_until` would have also
608731
/// yielded an error.
732+
///
733+
/// # Examples
734+
///
735+
/// A locked standard input implements `BufRead`. In this example, we'll
736+
/// read some input from standard input, splitting on commas.
737+
///
738+
/// ```
739+
/// use std::io;
740+
/// use std::io::prelude::*;
741+
///
742+
/// let stdin = io::stdin();
743+
///
744+
/// for content in stdin.lock().split(b',') {
745+
/// println!("{:?}", content.unwrap());
746+
/// }
747+
/// ```
609748
#[stable(feature = "rust1", since = "1.0.0")]
610749
fn split(self, byte: u8) -> Split<Self> where Self: Sized {
611750
Split { buf: self, delim: byte }
@@ -616,6 +755,21 @@ pub trait BufRead: Read {
616755
/// The iterator returned from this function will yield instances of
617756
/// `io::Result<String>`. Each string returned will *not* have a newline
618757
/// byte (the 0xA byte) at the end.
758+
///
759+
/// # Examples
760+
///
761+
/// A locked standard input implements `BufRead`:
762+
///
763+
/// ```
764+
/// use std::io;
765+
/// use std::io::prelude::*;
766+
///
767+
/// let stdin = io::stdin();
768+
///
769+
/// for line in stdin.lock().lines() {
770+
/// println!("{}", line.unwrap());
771+
/// }
772+
/// ```
619773
#[stable(feature = "rust1", since = "1.0.0")]
620774
fn lines(self) -> Lines<Self> where Self: Sized {
621775
Lines { buf: self }

0 commit comments

Comments
 (0)