← Back to Go Course | Chapter 13: File IO & OS | Lesson 3 of 7

Writing Files

Writing a file is like jotting a note down and sealing it in an envelope on disk so it's still there even after your program finishes running.
Syntax
go
err := os.WriteFile("path", data, 0644)

f, err := os.Create("path")
defer f.Close()
f.WriteString("text")

Writing a File in One Call

os.WriteFile creates (or overwrites) a file with the given byte slice as its full contents, in a single convenient call -- the simplest way to save small amounts of data.

Example: Writing a File in One Call

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the packages this program uses
import (
	"fmt"
	"io/ioutil"
)

// main is where the program starts running
func main() {
	// Short declaration: create err and infer the type
	err := ioutil.WriteFile("output.txt", []byte("Go makes file I/O simple"), 0644)
	// Handle the error if one occurred
	if err != nil {
		// Print the values followed by a newline
		fmt.Println("error:", err)
		return
	}
	// Print the values followed by a newline
	fmt.Println("file written successfully")
}

Writing Incrementally with os.Create

os.Create opens a file for writing, creating it if it doesn't exist or truncating it if it does, and returns a *os.File you can call Write on multiple times before closing.

Note: Always defer file.Close() to ensure buffered writes are flushed to disk.

Example: Writing Incrementally with os.Create

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the packages this program uses
import (
	"fmt"
	"os"
)

// main is where the program starts running
func main() {
	// Short declaration: create f, err and infer the type
	f, err := os.Create("log.txt")
	// Handle the error if one occurred
	if err != nil {
		// Print the values followed by a newline
		fmt.Println("error:", err)
		return
	}
	// defer runs this call when the surrounding function returns
	defer f.Close()

	f.WriteString("first line\n")
	f.WriteString("second line\n")
	// Print the values followed by a newline
	fmt.Println("wrote two lines")
}

Appending to an Existing File

To add data without erasing what's already there, open the file with os.OpenFile using the O_APPEND and O_WRONLY flags, rather than os.Create which always starts the file empty.

Example: Appending to an Existing File

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the packages this program uses
import (
	"fmt"
	"io/ioutil"
	"os"
)

// main is where the program starts running
func main() {
	ioutil.WriteFile("history.txt", []byte("entry 1\n"), 0644)

	// Short declaration: create f, err and infer the type
	f, err := os.OpenFile("history.txt", os.O_APPEND|os.O_WRONLY, 0644)
	// Handle the error if one occurred
	if err != nil {
		// Print the values followed by a newline
		fmt.Println("error:", err)
		return
	}
	// defer runs this call when the surrounding function returns
	defer f.Close()
	f.WriteString("entry 2\n")

	// Short declaration: create data, _ and infer the type
	data, _ := ioutil.ReadFile("history.txt")
	fmt.Println(string(data))
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Forgetting the permission bits argument to os.WriteFile (like 0644), which controls who can read/write the file.
  2. Opening a file with os.Create when you actually meant to append to an existing one -- Create always truncates.
  3. Not closing a file opened for writing before the program exits, risking buffered data never actually reaching disk.
Chapter Summary
  • os.WriteFile writes a full byte slice to a file in one call, creating or truncating it as needed.
  • os.Create opens (or truncates) a file for writing, requiring an explicit Close().
  • File permission bits, like 0644, control read/write/execute access on Unix-like systems.
  • os.OpenFile with the O_APPEND flag is used to add data to the end of an existing file.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.