Overview
Package io provides basic interfaces to I/O primitives. Its primary job is to wrap existing implementations of such primitives into shared public interfaces that abstract the functionality.
Core Interfaces
Reader
The interface that wraps the basic Read method.
type Reader interface {
Read(p []byte) (n int, err error)
}
Byte slice to read data into
Number of bytes read (0 to len(p))
Error encountered during read, or io.EOF at end
Example:
buf := make([]byte, 100)
n, err := reader.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
fmt.Printf("Read %d bytes\n", n)
Writer
The interface that wraps the basic Write method.
type Writer interface {
Write(p []byte) (n int, err error)
}
Byte slice containing data to write
Number of bytes written from p (0 to len(p))
Error that caused the write to stop early
Example:
data := []byte("Hello, World!")
n, err := writer.Write(data)
if err != nil {
log.Fatal(err)
}
Closer
The interface that wraps the basic Close method.
type Closer interface {
Close() error
}
Example:
Seeker
The interface that wraps the basic Seek method.
type Seeker interface {
Seek(offset int64, whence int) (int64, error)
}
Reference point: SeekStart (0), SeekCurrent (1), or SeekEnd (2)
New offset relative to start of file
Error encountered during seek
Example:
// Seek to beginning
file.Seek(0, io.SeekStart)
// Seek 10 bytes forward from current position
file.Seek(10, io.SeekCurrent)
// Seek to end
file.Seek(0, io.SeekEnd)
Composite Interfaces
ReadWriter
Groups the basic Read and Write methods.
type ReadWriter interface {
Reader
Writer
}
ReadCloser
Groups the basic Read and Close methods.
type ReadCloser interface {
Reader
Closer
}
WriteCloser
Groups the basic Write and Close methods.
type WriteCloser interface {
Writer
Closer
}
ReadWriteCloser
Groups Read, Write, and Close methods.
type ReadWriteCloser interface {
Reader
Writer
Closer
}
ReadSeeker
Groups the basic Read and Seek methods.
type ReadSeeker interface {
Reader
Seeker
}
Utility Functions
Copy
Copies from src to dst until EOF or error.
func Copy(dst Writer, src Reader) (written int64, err error)
First error encountered while copying, if any
Example:
src, _ := os.Open("source.txt")
dst, _ := os.Create("dest.txt")
defer src.Close()
defer dst.Close()
written, err := io.Copy(dst, src)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Copied %d bytes\n", written)
CopyN
Copies n bytes (or until an error) from src to dst.
func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
Example:
// Copy first 100 bytes
written, err := io.CopyN(dst, src, 100)
ReadAll
Reads from r until an error or EOF and returns the data it read.
func ReadAll(r Reader) ([]byte, error)
Reader to read all data from
All data read from the reader
Error encountered (EOF is not treated as an error)
Example:
data, err := io.ReadAll(reader)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Read %d bytes\n", len(data))
ReadFull
Reads exactly len(buf) bytes from r into buf.
func ReadFull(r Reader, buf []byte) (n int, err error)
Buffer to fill completely
Example:
buf := make([]byte, 100)
n, err := io.ReadFull(reader, buf)
if err != nil {
log.Fatal(err)
}
// buf is now completely filled
ReadAtLeast
Reads from r into buf until it has read at least min bytes.
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
Minimum number of bytes to read
WriteString
Writes the contents of string s to w.
func WriteString(w Writer, s string) (n int, err error)
Example:
n, err := io.WriteString(writer, "Hello, World!")
Special Readers and Writers
LimitReader
Returns a Reader that reads from r but stops with EOF after n bytes.
func LimitReader(r Reader, n int64) Reader
Maximum number of bytes to read
Example:
// Read at most 100 bytes
limited := io.LimitReader(file, 100)
data, _ := io.ReadAll(limited)
TeeReader
Returns a Reader that writes to w what it reads from r.
func TeeReader(r Reader, w Writer) Reader
Example:
var buf bytes.Buffer
tee := io.TeeReader(file, &buf)
io.ReadAll(tee) // Reads from file and writes to buf
NopCloser
Returns a ReadCloser with a no-op Close method wrapping the provided Reader.
func NopCloser(r Reader) ReadCloser
Example:
rc := io.NopCloser(strings.NewReader("data"))
defer rc.Close() // Close does nothing but satisfies interface
Variables
EOF
The error returned by Read when no more input is available.
var EOF = errors.New("EOF")
Example:
n, err := reader.Read(buf)
if err == io.EOF {
fmt.Println("Reached end of file")
}
ErrUnexpectedEOF
Means that EOF was encountered in the middle of reading a fixed-size block or data structure.
var ErrUnexpectedEOF = errors.New("unexpected EOF")
ErrShortWrite
Means that a write accepted fewer bytes than requested but failed to return an explicit error.
var ErrShortWrite = errors.New("short write")
ErrShortBuffer
Means that a read required a longer buffer than was provided.
var ErrShortBuffer = errors.New("short buffer")
Discard
A Writer on which all Write calls succeed without doing anything.
var Discard Writer = discard{}
Example:
// Discard all output
io.Copy(io.Discard, reader)
Complete Example
package main
import (
"fmt"
"io"
"os"
"strings"
)
func main() {
// Reading from a string
reader := strings.NewReader("Hello, World!")
// Copy to stdout
io.Copy(os.Stdout, reader)
fmt.Println()
// Read with limit
reader = strings.NewReader("0123456789")
limited := io.LimitReader(reader, 5)
data, _ := io.ReadAll(limited)
fmt.Printf("Limited read: %s\n", data) // Output: 01234
// Tee reader
var buf strings.Builder
reader = strings.NewReader("test")
tee := io.TeeReader(reader, &buf)
io.Copy(io.Discard, tee)
fmt.Printf("Tee captured: %s\n", buf.String())
}