Working with the File System in Go: From Basics to Advanced Techniques
Go (Golang) is a modern compiled programming language known for its performance, simplicity, and built-in support for working with the file system. The ability to efficiently read, write, create, and manage files and directories is one of the key skills for any Go developer. In this article, we will thoroughly examine basic file system operations using the standard library os, io/ioutil (starting with Go 1.16 it is recommended to use os and io) and path/filepath. You will learn how to open and close files, read and write data, work with directories, and traverse file trees.
1. Basics: Opening, Reading, and Writing Files
Working with files in Go starts with the os package. To open a file, use the os.Open function (read-only) or os.OpenFile (for reading and writing with mode specification). After finishing work, the file must be closed using defer file.Close() to free system resources.
Reading a File Entirely
The simplest way to read a file is to use os.ReadFile (available since Go 1.16). It returns a byte slice and an error.
package main
import ( "fmt" "os")
func main() { data, err := os.ReadFile("example.txt") if err != nil { fmt.Println("Error reading file:", err) return } fmt.Println("File contents:") fmt.Println(string(data))}Writing to a File
To write data to a file, use os.WriteFile. It creates or overwrites a file.
package main
import ( "os")
func main() { content := []byte("Hello, world!This is a line to write.") err := os.WriteFile("output.txt", content, 0644) if err != nil { panic(err) }}Note the third argument — 0644. This is the file permission in Unix-style (owner can read and write, others can only read).
Reading and Writing with Buffering
For large files or streaming processing, use bufio:
package main
import ( "bufio" "fmt" "os")
func main() { file, err := os.Open("large.txt") if err != nil { panic(err) } defer file.Close()
scanner := bufio.NewScanner(file) for scanner.Scan() { fmt.Println(scanner.Text()) } if err := scanner.Err(); err != nil { fmt.Println("Scanning error:", err) }}2. Working with Directories
Go provides convenient functions for creating, deleting, and reading directories. The main ones are in the os package.
Creating a Directory
To create a single directory, use os.Mkdir, for nested directories — os.MkdirAll.
package main
import ( "os")
func main() { // Create a single directory err := os.Mkdir("newdir", 0755) if err != nil { panic(err) }
// Create nested directories err = os.MkdirAll("path/to/nested/dir", 0755) if err != nil { panic(err) }}Reading Directory Contents
The os.ReadDir function returns a list of entries in a directory (since Go 1.16).
package main
import ( "fmt" "os")
func main() { entries, err := os.ReadDir(".") if err != nil { panic(err) }
for _, entry := range entries { fmt.Println(entry.Name(), entry.IsDir()) }}Deleting Files and Directories
For deletion, use os.Remove (for a file or empty directory) and os.RemoveAll