fmt, io, os, bufio, encoding/json, net/http, time, slog, regexp, flag, embed.
os and Files
The os package gives you the operating-system primitives — files, environment,
process info, signals.
Args and env
fmt.Println(os.Args) // []string{program, arg1, arg2, ...}
fmt.Println(os.Getenv("HOME"))
os.Setenv("DEBUG", "1")
Reading and writing files
The simplest reads and writes:
data, err := os.ReadFile("config.toml")
if err != nil { return err }
fmt.Println(string(data))
err = os.WriteFile("out.txt", []byte("hello\n"), 0o644)
os.ReadFile and os.WriteFile are perfect for small files. For anything large
or streaming, use os.Open / os.Create and a bufio.Scanner:
bufio — buffered I/O
| Type | Use |
| ---------------- | ------------------------------------ |
| bufio.Reader | Wrap an io.Reader for buffered reads. |
| bufio.Writer | Wrap an io.Writer for buffered writes (call Flush at the end). |
| bufio.Scanner | Line-by-line (or token-by-token) reading. |
bufio.NewScanner(os.Stdin) is the standard way to read user input from the
terminal.
File modes and paths
os.MkdirAll("logs/2024", 0o755)
os.Remove("temp.txt")
os.Rename("a", "b")
import "path/filepath"
filepath.Join("dir", "file.txt")
filepath.Ext("notes.md") // ".md"
filepath.Base("/usr/bin/go") // "go"
filepath is the cross-platform path helper. Don't concatenate paths with / —
use filepath.Join and your code works on Windows too.
Running external commands: os/exec
import "os/exec"
out, err := exec.Command("git", "rev-parse", "HEAD").Output()
if err != nil { return err }
fmt.Println(string(out))
exec.Command does not invoke a shell — exec.Command("ls", "-la *.go")
will literally look for a flag named -la *.go. To use shell features, run
exec.Command("sh", "-c", "ls -la *.go") — and beware of shell injection if any
input comes from outside.