Go Tutorial · Standard Library · Lesson 27 of 30

Go File Handling

Read and write files with the os and bufio packages.

Whole files

os.WriteFile and os.ReadFile handle small files in one call:

Example 1
package main

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

func main() {
	path := filepath.Join(os.TempDir(), "notes.txt")
	if err := os.WriteFile(path, []byte("first\nsecond\nthird\n"), 0o644); err != nil {
		fmt.Println("write failed:", err)
		return
	}
	defer os.Remove(path)

	data, err := os.ReadFile(path)
	fmt.Println(len(data), "bytes", err)

	f, err := os.Open(path)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer f.Close()
	scanner := bufio.NewScanner(f)
	n := 0
	for scanner.Scan() {
		n++
		fmt.Println(n, strings.ToUpper(scanner.Text()))
	}

	_, err = os.ReadFile("/does/not/exist")
	fmt.Println(errors.Is(err, os.ErrNotExist))
}

Output

19 bytes <nil>
1 FIRST
2 SECOND
3 THIRD
true

Run this on your computer — see “Get Started” for setup.

Line by line

For large files, open the file and scan it line by line with bufio.Scanner. Always defer f.Close() right after a successful open.

The 0o644 argument is the Unix permission for a new file (owner read/write, everyone else read).

Test yourself

What should you do right after successfully opening a file?

  1. Nothing
  2. defer f.Close()
  3. Call f.Flush()
  4. Set a finalizer
Show answer

Answer: defer f.Close()