Packages: Core Packages: Files and Folders - kyunghoj/golang GitHub Wiki

Packages

The Core Packages

Files and Folders

To open a file in Go, use the Open function from the os package. Here is an example of how to read the contents of a file and display them on the terminal:

package main

import (
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("test.txt")
    if err != nil {
        // handle the error here
        return
    }
    defer file.Close()

    // get the file size
    stat, err := file.Stat()
    if err != nil {
        return
    }
    // read the file
    bs := make([]byte, stat.Size())
    _, err = file.Read(bs)
    if err != nil {
        return
    }

    str := string(bs)
    fmt.Println(str)
}

Reading files is very common, so there's a shorter way to do this:

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    bs, err := ioutil.ReadFile("test.txt")
    if err != nil {
        return
    }
    str := string(bs)
    fmt.Println(str)
}

To create a file, use the os.Create function. It takes the name of the file, creates it in the current working directory, and returns an os.File and possibly an error (if it was unable to create it for some reason). Here's an example program:

package main

import (
    "os"
)

func main() {
    file, err := os.Create("test.txt")
    if err != nil {
        // handle the error here
        return
    }
    defer file.Close()

    file.WriteString("test")
}

To get the contents of a directory, we use the same os.Oepn function but give it a directory path instead of a file name. Then we call the Readdir method:

package main

import (
    "fmt"
    "os"
)

func main() {
    dir, err := os.Open(".")
    if err != nil {
        return
    }
    defer dir.Close()

    fileInfos, err := dir.Readdir(-1)
    if err != nil {
        return
    }
    for _, fi := range fileInfos {
        fmt.Println(fi.Name())
    }
}

Readdir takes a single argument that limits the number of entries returned. By passing in -1, we return all of the entries. Often, we want to recursively walk a folder (read the folder's contents, all the subfolders, all the sub-subfolders, etc.) To make this easier, there's a Walk function provided in the path/filepath package:

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func main() {
    filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
        fmt.Println(path)
        return nil
    })
}

The function you pass to Walk is called for every file and folder in the root folder (in this case .). It's passed three arguments: path, which is the path to the file; info, which is the information for the file (the same information you get from using os.Stat); and err.