DMarlon Studio

Lesson 19 · 19 of 20

Writing and reading files · Go

Write and read text files in Go with the os package: WriteFile, OpenFile to append, Open with bufio.Scanner, and defer to close.

Go · Writing and reading files in DMarlon Studio: the example's code and its output in the terminal

os.WriteFile creates a file (or replaces it if it already exists) with the content you pass, turned into bytes with []byte(notes). 0644 are the file's permissions on Unix-like systems: read and write for you, read-only for everyone else. The name notes.txt, with no folder, puts it in the current folder.

Nearly everything that touches files can fail, so it returns an error. The check function saves repeating the same test: if err is not nil, it prints it and ends the program with os.Exit(1).

To append without wiping what is there, os.OpenFile opens the file with os.O_APPEND|os.O_WRONLY: write at the end, and write only. fmt.Fprintln(f, ...) works like Println but writes into the file f. Then f.Close() closes it.

os.Open opens the file for reading and a bufio.Scanner, like the one in lesson 5, walks through it line by line: for n := 1; scanner.Scan(); n++ numbers the lines while there are any left. `defer` postpones file.Close() until main ends; it is the usual way not to forget to close a file. To read a whole file in one go there is also os.ReadFile.

Code · main.go

package mainimport (	"bufio"	"fmt"	"os")// check stops the program if something went wrong.func check(err error) {	if err != nil {		fmt.Println("Error:", err)		os.Exit(1)	}}func main() {	// WriteFile creates (or replaces) a file in the current folder.	notes := "Buy bread\nCall the plumber\nWater the plants\n"	check(os.WriteFile("notes.txt", []byte(notes), 0644))	// OpenFile with O_APPEND adds lines at the end.	f, err := os.OpenFile("notes.txt", os.O_APPEND|os.O_WRONLY, 0644)	check(err)	fmt.Fprintln(f, "Pay the electricity bill")	f.Close()	// Open + bufio.Scanner reads it back line by line.	file, err := os.Open("notes.txt")	check(err)	defer file.Close() // runs when main ends	scanner := bufio.NewScanner(file)	for n := 1; scanner.Scan(); n++ {		fmt.Printf("%d. %s\n", n, scanner.Text())	}}

Output · go run main.go

1. Buy bread
2. Call the plumber
3. Water the plants
4. Pay the electricity bill

Key points

  • os.WriteFile creates or replaces a file.
  • os.OpenFile with os.O_APPEND adds at the end.
  • fmt.Fprintln(f, ...) writes into a file.
  • os.Open and bufio.Scanner read line by line.
  • defer f.Close() closes the file when the function ends.

Exercise

Write a prices.txt file with one price per line, read it with a Scanner, convert each line with strconv.ParseFloat and print the sum.