liveBook · Manning

Io.Reader

As explained in Go in Action, Second Edition

io.Reader is the Go interface for reading a stream of bytes into a supplied buffer.

A function that reads input need not depend on a file. Accepting an io.Reader lets the same processing code consume a file, standard input, a memory buffer, or another data source. The interface specifies reading behavior rather than where the bytes come from. section 10.3

Listing 2.40 Excerpt from go doc io.Reader
type Reader interface {
        Read(p []byte) (n int, err error)
}
    Reader is the interface that wraps the basic Read method.

    Read reads up to len(p) bytes into p. It returns the number of bytes
    read (0 <= n <= len(p)) and any error encountered. Even if Read returns
    n < len(p), it may use all of p as scratch space during the call. If
    some data is available but not len(p) bytes, Read conventionally returns
    what is available instead of waiting for more.

The interface has one method: Read fills a supplied byte slice with up to len(p) bytes and returns the number read and any error. A read can return fewer bytes than the buffer holds. section 2.8.2

Count words in a file

os.Open returns an *os.File, whose Read method satisfies io.Reader. Pass it to bufio.NewScanner, then check both the open error and the scanner error: func countWords(path string) (int, error) { file, err := os.Open(path) if err != nil { return 0, err } defer file.Close() scanner := bufio.NewScanner(file) count := 0 for scanner.Scan() { count += len(strings.Fields(scanner.Text())) } return count, scanner.Err() } section 2.8.2 section 2.8.1

Use io.Reader at an input boundary when processing should not care which source supplies the bytes. Pair it with io.Writer for destination-independent output; use a combined interface such as io.ReadCloser when the caller also needs closing behavior. section 10.3

How Go in Action, Second Edition covers it

How deep it goes
Defines Read’s signature and partial-read behavior, then demonstrates interface compatibility without implementing a custom Reader.
Examples
Uses a file-backed word counter and source-independent input for a JSON/XML conversion CLI.
What it assumes
Assumes basic familiarity with Go interfaces and byte slices while showing how to inspect the interface with go doc.
What you can do after
Apply it via os.Open and bufio.NewScanner to process a file without coupling scanning logic to the file type.
How it connects
Connects io.Reader to bufio.Scanner, os.File, io.Writer, and io.ReadCloser.

Also explained in

Compare how 3 books explain io.Reader →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Action, Second Edition. The section links point to the parts of the book it draws on.