• English
  • Example: io.ReadAll

    io.ReadAll reads from an io.Reader until EOF and returns all successfully read bytes as a []byte.

    Use it when the input is bounded and small enough to keep in memory.

    Typical examples include configuration files, small HTTP responses, JSON payloads, and test data.

    Quick Example

    package main
    
    import (
    	"fmt"
    	"io"
    	"strings"
    )
    
    func main() {
    	src := strings.NewReader("Hello, io.ReadAll from gobase.net.\n")
    
    	data, err := io.ReadAll(src)
    	if err != nil {
    		fmt.Println("read failed:", err)
    		return
    	}
    
    	fmt.Printf("%s", data)
    }

    io.ReadAll does not return until the reader reaches EOF or an error occurs.

    The returned []byte contains the entire input, so memory usage grows with the amount of data read.

    Common Use

    Read a small, bounded file into memory:

    file, err := os.Open("config.json")
    if err != nil {
    	return err
    }
    defer file.Close()
    
    data, err := io.ReadAll(file)
    if err != nil {
    	return err
    }
    
    fmt.Println(string(data))

    This is a reasonable choice for configuration files, certificates, templates, and other resources whose size is known and limited.

    For a small config.json, keeping the entire file in memory is usually simpler than introducing streaming logic.

    HTTP Response Bodies

    For HTTP responses, limit the input when the response size is not fully trusted:

    resp, err := http.Get("https://example.com/data.json")
    if err != nil {
    	return err
    }
    defer resp.Body.Close()
    
    body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
    if err != nil {
    	return err
    }
    
    fmt.Printf("response size: %d bytes\n", len(body))

    io.LimitReader caps the amount of data passed to io.ReadAll, preventing an unexpectedly large response from being fully buffered in memory.

    Common Mistakes

    1. Using io.ReadAll for large or unbounded input

    This loads the entire input into memory:

    data, err := io.ReadAll(src)

    For large files, streams, or untrusted input, prefer streaming with io.Copy or process the data incrementally.

    2. Reading untrusted input without a size limit

    io.ReadAll has no built-in maximum size.

    For input whose size is controlled by a remote client or external server, consider limiting it:

    data, err := io.ReadAll(io.LimitReader(src, 1<<20))

    The limit should match the actual maximum size your application expects.

    3. Converting to string unnecessarily

    If the next API accepts []byte, keep the returned byte slice:

    data, err := io.ReadAll(src)
    if err != nil {
    	return err
    }
    
    process(data)

    Only convert to string when a string is actually required.

    4. Assuming io.ReadAll returns io.EOF on success

    When the reader reaches EOF normally, io.ReadAll returns err == nil.

    io.EOF is consumed as the normal end of input.

    Rule of Thumb

    Use io.ReadAll when you intentionally want the entire input in memory; otherwise, keep the data streaming.