Working with the File System in Go: In Practice

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Working with the File System in Go: In Practice

\n\n

Working with the file system is one of the basic tasks of any server application. The Go language (Golang) provides a powerful and elegant toolkit for reading, writing, deleting, and managing files and directories. In this article, we will break down practical examples of working with files in Go, using the standard packages os, io/ioutil (before Go 1.16), and io. You will learn how to efficiently manage data on disk, handle errors, and write clean code.

\n\n

1. Basics: Opening, Reading, and Writing Files

\n\n

Let's start with the most common operations. To open a file, use the os.OpenFile function or the simpler wrappers os.Create and os.Open. Let's look at an example of reading an entire file into memory:

\n\n
package main\n\nimport (\n    "fmt"\n    "os"\n)\n\nfunc main() {\n    // Reading the entire file (before Go 1.16, we used ioutil.ReadFile)\n    data, err := os.ReadFile("example.txt")\n    if err != nil {\n        fmt.Println("Error reading file:", err)\n        return\n    }\n    fmt.Println("File contents:")\n    fmt.Println(string(data))\n}\n
\n\n

To write data to a file, use os.WriteFile:

\n\n
package main\n\nimport (\n    "os"\n)\n\nfunc main() {\n    content := []byte("Hello, Go world!\\nSecond line.")\n    err := os.WriteFile("output.txt", content, 0644)\n    if err != nil {\n        panic(err)\n    }\n    // The output.txt file is created and contains our text\n}\n
\n\n

If you need to append data to the end of a file, use flags:

\n\n
file, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\nif err != nil {\n    panic(err)\n}\ndefer file.Close()\n\nif _, err := file.WriteString("New log entry\\n"); err != nil {\n    panic(err)\n}\n
\n\n

2. Working with Directories: Creating, Deleting, and Traversing

\n\n

Managing folders is an equally important task. You can create a new directory using os.Mkdir (single folder) or os.MkdirAll (recursively, like mkdir -p):

\n\n
package main\n\nimport (\n    "fmt"\n    "os"\n)\n\nfunc main() {\n    // Create a single folder\n    err := os.Mkdir("data", 0755)\n    if err != nil {\n        fmt.Println("Error creating folder:", err)\n    }\n\n    // Recursively create a nested structure\n    err = os.MkdirAll("data/subdir/logs", 0755)\n    if err != nil {\n        fmt.Println("Error:", err)\n    }\n}\n
\n\n

To traverse a directory, you can use the os.ReadDir function (replacement for ioutil.ReadDir):

\n\n
entries, err := os.ReadDir(".")\nif err != nil {\n    panic(err)\n}\n\nfor _, entry := range entries {\n    fmt.Printf("Name: %s, Is Directory: %t\\n", entry.Name(), entry.IsDir())\n}\n
\n\n

And for recursive traversal of all files and folders, use filepath.Walk from the path/filepath package:

\n\n
package main\n\nimport (\n    "fmt"\n    "os"\n    "path/filepath"\n)\n\nfunc main() {\n    err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {\n        if err != nil {\n            return err\n        }\n        fmt.Println(path)\n        return nil\n    })\n    if err != nil {\n        fmt.Println("Error during traversal:", err)\n    }\n}\n
\n\n

Deleting files and folders is done with the os.Remove and os.RemoveAll functions:

\n\n
// Delete a single file or empty folder\nos.Remove("temp.txt")\n\n// Delete a folder with all its contents (analogous to rm -rf)\nos.RemoveAll("data")\n
\n\n

3. Advanced Techniques: Buffered Input/Output and Working with Temporary Files

\n\n

For large files, it is inefficient to read the entire content into memory. Use buffered reading with bufio:

\n\n
package main\n\nimport (\n    "bufio"\n    "                

Blogs

Book Recommendations