๐Ÿ“‚File I/OLESSON

File I/O

Go's standard library provides layered file I/O: simple whole-file helpers, low-level os file handles, and the composable io.Reader/io.Writer interfaces.

Simple whole-file operations

For small files where the entire content fits comfortably in memory:

The permission bits 0644 grant the owner read+write and everyone else read-only.

Opening and creating files

os.Open returns an *os.File for reading. os.Create creates (or truncates) a file for writing:

Always defer f.Close() immediately after a successful open โ€” it fires even if the function returns early or panics.

For more control over open flags and permissions, use os.OpenFile:

Common flag combinations:

FlagsUse case
os.O_RDONLYRead-only (default for os.Open)
os.O_WRONLYWrite-only
os.O_RDWRRead and write
os.O_CREATECreate if it doesn't exist
os.O_TRUNCTruncate to zero (default for os.Create)
os.O_APPENDAppend; every write goes to end of file

Line-by-line reading with bufio.Scanner

bufio.Scanner is the idiomatic way to read line by line:

io.Writer โ€” the complement to io.Reader

Just as io.Reader is the interface for reading, io.Writer is the interface for writing:

*os.File, bytes.Buffer, strings.Builder, and many more implement io.Writer. Write to any of them uniformly:

Streaming with io.Copy

io.Copy reads from a Reader and writes to a Writer in chunks โ€” no need to load the whole file into memory:

Path manipulation with path/filepath

path/filepath handles OS-specific path separators correctly (forward slash on Unix, backslash on Windows):

Temp files

os.CreateTemp creates a uniquely-named file for scratch data:

Knowledge Check

What is the idiomatic way to ensure a file is closed after opening it?

Which os.OpenFile flag combination appends to an existing file without truncating it?

What does io.Copy do?