List files in a directory using golang

Manigandan Dharmalingam
3 min readMar 8, 2018

--

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

https://gist.github.com/manigandand/19aa61c81aaabc0962157380e575c006#file-list_directory-go

Using filepath.Walk

The path/filepath package provides 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. Walk does not follow symbolic links.

package mainimport (
"io/ioutil"
"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

func (f *File) Readdir(n int) ([]FileInfo, error)

Readdir reads the contents of the directory associated with 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.

benchmark results
package mainimport (
"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)
}
}

--

--