0Pricing
Go Academy · Lesson

Buffered Readers

Read efficiently with bufio.

Buffered Readers is a free Go Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why Buffer Reads

Reading one byte at a time from a file or network triggers a syscall every time. That is slow.

The bufio package wraps a reader and reads in large chunks into an in-memory buffer, serving your small reads from that buffer.

  • Fewer syscalls
  • Much faster for many small reads

Creating a bufio.Reader

Wrap any io.Reader with bufio.NewReader. Here we wrap a strings.Reader.

package main

import (
	"bufio"
	"fmt"
	"strings"
)

func main() {
	r := bufio.NewReader(strings.NewReader("Hello, Go!"))
	fmt.Printf("buffered reader ready: %T\n", r)
}

Reading Bytes

ReadByte returns the next single byte. It is served from the buffer, not a fresh syscall.

package main

import (
	"bufio"
	"fmt"
	"strings"
)

func main() {
	r := bufio.NewReader(strings.NewReader("Go"))
	b1, _ := r.ReadByte()
	b2, _ := r.ReadByte()
	fmt.Printf("%c%c\n", b1, b2)
}

ReadString to a Delimiter

ReadString(delim) reads until the first occurrence of the delimiter byte, returning everything including the delimiter.

package main

import (
	"bufio"
	"fmt"
	"strings"
)

func main() {
	r := bufio.NewReader(strings.NewReader("first,second,third"))
	part, _ := r.ReadString(',')
	fmt.Printf("%q\n", part)
}

Peeking Ahead

Peek(n) returns the next n bytes without consuming them. Great for deciding how to parse before committing.

package main

import (
	"bufio"
	"fmt"
	"strings"
)

func main() {
	r := bufio.NewReader(strings.NewReader("HTTP/1.1"))
	head, _ := r.Peek(4)
	fmt.Printf("starts with: %s\n", head)
}

Buffer Size

bufio.NewReaderSize(r, size) sets the buffer capacity. A larger buffer means fewer underlying reads but more memory.

package main

import (
	"bufio"
	"fmt"
	"strings"
)

func main() {
	r := bufio.NewReaderSize(strings.NewReader("data"), 4096)
	fmt.Println("buffer size:", r.Size())
}

ReadLine vs ReadString

ReadString('\n') keeps the newline; many parsers prefer trimming it. The Scanner (next lesson) handles this automatically.

Use ReadString when you need full control over delimiters.

Handling io.EOF

When the underlying stream is exhausted, read methods return io.EOF. Always check for it to know when to stop.

package main

import (
	"bufio"
	"fmt"
	"io"
	"strings"
)

func main() {
	r := bufio.NewReader(strings.NewReader("ab"))
	for {
		c, err := r.ReadByte()
		if err == io.EOF {
			break
		}
		fmt.Printf("%c", c)
	}
	fmt.Println()
}

ReadRune for Unicode

ReadRune decodes a full UTF-8 rune, which may span multiple bytes. Use it for text with non-ASCII characters.

package main

import (
	"bufio"
	"fmt"
	"strings"
)

func main() {
	r := bufio.NewReader(strings.NewReader("héllo"))
	for {
		ru, _, err := r.ReadRune()
		if err != nil {
			break
		}
		fmt.Printf("%c ", ru)
	}
	fmt.Println()
}

Reading Until Done

A common pattern: loop with ReadString until EOF to process a stream line by line while keeping fine control.

package main

import (
	"bufio"
	"fmt"
	"io"
	"strings"
)

func main() {
	r := bufio.NewReader(strings.NewReader("a\nb\nc\n"))
	for {
		line, err := r.ReadString('\n')
		fmt.Print("got: " + line)
		if err == io.EOF {
			break
		}
	}
}

When to Use bufio.Reader

  • Wrapping slow sources (files, sockets)
  • Many small reads
  • Need to peek or read by delimiter/rune

For simple line scanning, prefer bufio.Scanner (next lesson).

Quick Check

Test your understanding of buffered readers.

Recap

You learned how bufio.Reader reduces syscalls by buffering.

  • NewReader / NewReaderSize wrap an io.Reader
  • ReadByte, ReadRune, ReadString serve from the buffer
  • Peek looks ahead without consuming
  • Stop on io.EOF

Frequently asked questions

Is the “Buffered Readers” lesson free?

Yes — the full text of “Buffered Readers” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.

What will I learn in “Buffered Readers”?

Read efficiently with bufio. You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Go Academy?

No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Buffered Readers” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Go Academy lesson?

Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Buffered Readers
  2. Scanners
  3. Buffered Writers
  4. Streaming Large Files
← Back to Go Academy