Golang Manipulate files Traverse directories to get a list of files

This article will list three methods

filepath.Walk
ioutil.ReadDir
os.File.Readdir

use filepath.Walk

The path/filepath standard library package provides a convenient Walk method that automatically scans subdirectories and is easy to use

package main
import (
    "fmt"
    "os"
    "path/filepath"
)
func main() {
    var files []string
    root := "/some/folder/to/scan"
    err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
        files = append(files, path)
        return nil
    })
    if err != nil {
        panic(err)
    }
    for _, file := range files {
        fmt.Println(file)
    }
}

Use ioutil.ReadDir

filepath.Walk is handy but it scans all subfolders by default, but this is sometimes not what we want

Go’s standard library also provides ioutil.ReadDir

ioutil.ReadDir takes a folder path of type string and returns a slice of os.FileInfo, mentioned above.

package main
import (
    "fmt"
    "io/ioutil"
    "log"
)
func main() {
    files, err := ioutil.ReadDir(".")
    if err != nil {
        log.Fatal(err)
    }
    for _, file := range files {
        fmt.Println(file.Name())
    }
}

Use os.File.Readdir

The internal implementation of ReadDir

// ReadDir reads the directory named by dirname and returns
// a list of directory entries sorted by filename.
func ReadDir(dirname string) ([]os.FileInfo, error) {
    f, err := os.Open(dirname)
    if err != nil {
        return nil, err
    }
    list, err := f.Readdir(-1)
    f.Close()
    if err != nil {
        return nil, err
    }
    sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
    return list, nil
}

We can see that it only scans the folder directory and then sorts the files by name. If we don’t need this ordering we can do this:

package main
import (
    "fmt"
    "log"
    "os"
)
func main() {
    dirname := "."
    f, err := os.Open(dirname)
    if err != nil {
        log.Fatal(err)
    }
    files, err := f.Readdir(-1)
    f.Close()
    if err != nil {
        log.Fatal(err)
    }
    for _, file := range files {
        fmt.Println(file.Name())
    }
}

Go to get the absolute path of the current project

package main
import (
     "fmt"
     "os"
     "path/filepath"
)
func main() {
     //Get the absolute path of the current project
     path, err2 := os.Executable()
     if err2 != nil {
         fmt.Println(err2)
     }
     dir := filepath.Dir(path)
     fmt.Println("111", path) // /Users/mac/repose/idphoto_server_lite/test/test3
     fmt.Println("2222", dir) // /Users/mac/repose/idphoto_server_lite/test
}

Leave a Reply

Your email address will not be published. Required fields are marked *

en_USEnglish