CodeNebula
Go📦Standard Libraryintermediate

bufio — Buffered I/O

Go · Standard Library · Run with go run

Explanation

`bufio.Scanner` reads input line-by-line (or by custom split functions). `bufio.Reader` adds buffering to any `io.Reader`, reducing system calls. `bufio.Writer` buffers writes and flushes in larger chunks. Essential for performance when reading or writing many small pieces of data.

Real-World Scenario

Reading a 10 GB log file line by line: `bufio.Scanner` reads chunks (default 64KB) from the OS and splits on newlines, keeping only one line in memory at a time — far more efficient than `io.ReadAll`.

Quick Snippet

snippet.go
import (
    "bufio"
    "os"
)

// Read a file line by line
f, _ := os.Open("large.log")
defer f.Close()

scanner := bufio.NewScanner(f)
for scanner.Scan() {
    line := scanner.Text()
    process(line)
}
if err := scanner.Err(); err != nil {
    log.Fatal(err)
}

// Buffered writer — flush at the end
bw := bufio.NewWriter(os.Stdout)
defer bw.Flush()
fmt.Fprintln(bw, "buffered output")

Full Example

bufio_scanner.go
// Compile: go run bufio_scanner.go
// Output:
//   line 1: alpha
//   line 2: beta
//   line 3: gamma
//   words: 4
package main

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

func main() {
	input := "alpha\nbeta\ngamma"

	// Scan line by line
	scanner := bufio.NewScanner(strings.NewReader(input))
	lineNo := 0
	for scanner.Scan() {
		lineNo++
		fmt.Printf("line %d: %s\n", lineNo, scanner.Text())
	}

	// Custom split function — scan words
	ws := bufio.NewScanner(strings.NewReader("the quick brown fox"))
	ws.Split(bufio.ScanWords)
	count := 0
	for ws.Scan() {
		count++
	}
	fmt.Println("words:", count)
}
Run command
go run bufio_scanner.go