We can get a list of files inside a folder on the file system using various Golang standard library functions.
- filepath.Walk
- ioutil.ReadDir
- os.File.Readdir
Source: https://gist.github.com/manigandand/19aa61c81aaabc0962157380e575c006#file-list_directory-go
Using filepath.Walk
The
path/filepath
package provides a handy way to scan all the files in a directory, it will automatically scan each sub-directories in the directory.
Walk walks the file tree rooted at root, calling walkFn for each file or directory in the tree, including root. All errors that arise visiting files and directories are filtered by walkFn. The files are walked in lexical order, which makes the output deterministic but means that for very large directories Walk can be inefficient. The walk does not follow symbolic links.
package main
import (
"fmt"
"log"
"os"
"path/filepath"
)
func main() {
var root string
if len(os.Args) == 1 {
log.Fatal("No path given, Please specify path.")
return
}
if root = os.Args[1]; root == "" {
log.Fatal("No path given, Please specify path.")
return
}
// filepath.Walk
files, err := FilePathWalkDir(root)
if err != nil {
panic(err)
}
for _, file := range files {
fmt.Println(file)
}
}
func FilePathWalkDir(root string) ([]string, error) {
var files []string
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
files = append(files, path)
}
return nil
})
return files, err
}
Using ioutil.ReadDir
ioutil.ReadDir reads the directory named by dirname and returns a list of directory entries sorted by filename.
func IOReadDir(root string) ([]string, error) {
var files []string
fileInfo, err := ioutil.ReadDir(root)
if err != nil {
return files, err
}
for _, file := range fileInfo {
files = append(files, file.Name())
}
return files, nil
}
Using os.File.Readdir
Readdir reads the contents of the directory associated with the file and returns a slice of up to n FileInfo values, as would be returned by Lstat, in directory order. Subsequent calls on the same file will yield further FileInfos.
func OSReadDir(root string) ([]string, error) {
var files []string
f, err := os.Open(root)
if err != nil {
return files, err
}
fileInfo, err := f.Readdir(-1)
f.Close()
if err != nil {
return files, err
}
for _, file := range fileInfo {
files = append(files, file.Name())
}
return files, nil
}
See the benchmark result of these three functions.
package main
import (
"testing"
)
var root string = "/home/manigandan/Desktop/Manigandan/sample"
func BenchmarkFilePathWalkDir1(b *testing.B) { benchmarkFilePathWalkDir(1, root, b) }
func BenchmarkFilePathWalkDir2(b *testing.B) { benchmarkFilePathWalkDir(2, root, b) }
func BenchmarkFilePathWalkDir3(b *testing.B) { benchmarkFilePathWalkDir(3, root, b) }
func BenchmarkFilePathWalkDir10(b *testing.B) { benchmarkFilePathWalkDir(10, root, b) }
func BenchmarkFilePathWalkDir20(b *testing.B) { benchmarkFilePathWalkDir(20, root, b) }
func BenchmarkFilePathWalkDir30(b *testing.B) { benchmarkFilePathWalkDir(30, root, b) }
func BenchmarkFilePathWalkDir40(b *testing.B) { benchmarkFilePathWalkDir(40, root, b) }
func BenchmarkFilePathWalkDir50(b *testing.B) { benchmarkFilePathWalkDir(50, root, b) }
func BenchmarkIOReadDir1(b *testing.B) { benchmarkIOReadDir(1, root, b) }
func BenchmarkIOReadDir2(b *testing.B) { benchmarkIOReadDir(2, root, b) }
func BenchmarkIOReadDir3(b *testing.B) { benchmarkIOReadDir(3, root, b) }
func BenchmarkIOReadDir10(b *testing.B) { benchmarkIOReadDir(10, root, b) }
func BenchmarkIOReadDir20(b *testing.B) { benchmarkIOReadDir(20, root, b) }
func BenchmarkIOReadDir30(b *testing.B) { benchmarkIOReadDir(30, root, b) }
func BenchmarkIOReadDir40(b *testing.B) { benchmarkIOReadDir(40, root, b) }
func BenchmarkIOReadDir50(b *testing.B) { benchmarkIOReadDir(50, root, b) }
func BenchmarkOSReadDir1(b *testing.B) { benchmarkOSReadDir(1, root, b) }
func BenchmarkOSReadDir2(b *testing.B) { benchmarkOSReadDir(2, root, b) }
func BenchmarkOSReadDir3(b *testing.B) { benchmarkOSReadDir(3, root, b) }
func BenchmarkOSReadDir10(b *testing.B) { benchmarkOSReadDir(10, root, b) }
func BenchmarkOSReadDir20(b *testing.B) { benchmarkOSReadDir(20, root, b) }
func BenchmarkOSReadDir30(b *testing.B) { benchmarkOSReadDir(30, root, b) }
func BenchmarkOSReadDir40(b *testing.B) { benchmarkOSReadDir(40, root, b) }
func BenchmarkOSReadDir50(b *testing.B) { benchmarkOSReadDir(50, root, b) }
func benchmarkFilePathWalkDir(i int, root string, b *testing.B) {
// run the FilePathWalkDir function b.N times
for n := 0; n < b.N; n++ {
FpW(i, root)
}
}
func benchmarkIOReadDir(i int, root string, b *testing.B) {
// run the IOReadDir function b.N times
for n := 0; n < b.N; n++ {
IoRdir(i, root)
}
}
func benchmarkOSReadDir(i int, root string, b *testing.B) {
// run the OSReadDir function b.N times
for n := 0; n < b.N; n++ {
OsRdir(i, root)
}
}
Top comments (1)
But in the first solution you included Logging,
its not fair with the other 2 solutions as is doing extra stuff.
My Nim solution :)