Lesson 21: File Handling in GoLang

In Lesson 21, we explore how to manage files and directories in GoLang. File handling is essential in applications that require reading from or writing to files, managing file paths, and creating or removing directories.


1. Reading Files in GoLang

To read files in GoLang, we use the os and io/ioutil packages. These packages provide functions to open files, read their contents, and close them afterward.

Reading Entire File

The simplest way to read an entire file into memory is using ioutil.ReadFile.

Example:

Go
package main

import (
    "fmt"
    "io/ioutil"
    "log"
)

func main() {
    content, err := ioutil.ReadFile("example.txt")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(content))
}

Explanation:

  • ioutil.ReadFile("example.txt"): Reads the entire file’s content into the content variable.
  • string(content): Converts the file’s content from a byte slice to a string for display.
Reading File Line by Line

To read a file line by line, you can use the bufio.Scanner.

Example:

Go
package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("example.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }

    if err := scanner.Err(); err != nil {
        fmt.Println(err)
    }
}

Explanation:

  • os.Open("example.txt"): Opens the file for reading.
  • bufio.NewScanner(file): Creates a scanner to read the file line by line.
  • scanner.Text(): Reads each line as a string.

2. Writing Files in GoLang

To write to files, we use the os package. You can either overwrite an existing file or append to a file.

Writing to a New File

You can create a new file (or overwrite an existing file) using os.Create.

Example:

Go
package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Create("output.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()

    _, err = file.WriteString("Hello, GoLang!")
    if err != nil {
        fmt.Println(err)
    }
}

Explanation:

  • os.Create("output.txt"): Creates a new file named output.txt.
  • file.WriteString("Hello, GoLang!"): Writes the string to the file.
Appending to a File

To append content to an existing file, open it with the os.O_APPEND flag.

Example:

Go
package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.OpenFile("output.txt", os.O_APPEND|os.O_WRONLY, 0644)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()

    _, err = file.WriteString("\nAppended text!")
    if err != nil {
        fmt.Println(err)
    }
}

Explanation:

  • os.OpenFile("output.txt", os.O_APPEND|os.O_WRONLY, 0644): Opens the file in append mode (os.O_APPEND) with write permissions (os.O_WRONLY).
  • file.WriteString("\nAppended text!"): Appends the string to the file.

3. Managing File Paths

File paths are handled using the path/filepath package. This package offers utilities to manipulate and construct file paths in a cross-platform manner.

Getting File Name and Extension

You can extract the base name and extension of a file using filepath.Base and filepath.Ext.

Example:

Go
package main

import (
    "fmt"
    "path/filepath"
)

func main() {
    path := "example.txt"
    fmt.Println("Base:", filepath.Base(path))
    fmt.Println("Extension:", filepath.Ext(path))
}

Explanation:

  • filepath.Base(path): Returns the last element of the path (example.txt).
  • filepath.Ext(path): Returns the file extension (.txt).
Constructing Paths

You can build a file path that works across operating systems using filepath.Join.

Example:

Go
package main

import (
    "fmt"
    "path/filepath"
)

func main() {
    path := filepath.Join("dir", "subdir", "file.txt")
    fmt.Println(path)
}

Explanation:

  • filepath.Join("dir", "subdir", "file.txt"): Joins directory and file names into a single path (dir/subdir/file.txt).

4. Working with Directories

GoLang also provides functions to create and remove directories.

Creating a Directory

To create a new directory, use os.Mkdir.

Example:

Go
package main

import (
    "fmt"
    "os"
)

func main() {
    err := os.Mkdir("newdir", 0755)
    if err != nil {
        fmt.Println(err)
    }
}

Explanation:

  • os.Mkdir("newdir", 0755): Creates a directory named newdir with permissions 0755.
Removing Files and Directories

You can remove files and directories using os.Remove.

Example:

Go
package main

import (
    "fmt"
    "os"
)

func main() {
    err := os.Remove("output.txt")
    if err != nil {
        fmt.Println(err)
    }
}

Explanation:

  • os.Remove("output.txt"): Removes the file or directory.
Temporary Files and Directories

To create temporary files or directories, use os.CreateTemp and os.MkdirTemp.

Example (Temporary File):

Go
package main

import (
    "fmt"
    "os"
)

func main() {
    tempFile, err := os.CreateTemp("", "example-*.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer os.Remove(tempFile.Name()) // Clean up

    fmt.Println("Temporary file created:", tempFile.Name())
}

5. The Embed Directive

Starting with Go 1.16, the embed directive allows you to embed files and static content directly in the Go binary.

Embedding Files

To embed a file, use the //go:embed directive.

Example:

Go
package main

import (
    _ "embed"
    "fmt"
)

//go:embed example.txt
var embeddedFile string

func main() {
    fmt.Println("Embedded file content:")
    fmt.Println(embeddedFile)
}

Explanation:

  • //go:embed example.txt: Embeds the content of example.txt in the embeddedFile variable.

Key Takeaways:

  • GoLang provides a rich set of tools for reading, writing, and managing files and directories.
  • You can manipulate file paths in a cross-platform way using the path/filepath package.
  • Temporary files and the embed directive allow for efficient management of static content.
Scroll to Top