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
}