List files in a directory using Golang
Tags: go
Published: 2020-01-09 09:25:17

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](https://golang.org/pkg/path/filepath/#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.

```golang
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](https://golang.org/pkg/io/ioutil/#ReadDir) reads the directory named by dirname and returns a list of directory entries sorted by filename.


```golang

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](https://golang.org/pkg/io/ioutil/#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.


```golang

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](https://cdn-images-1.medium.com/max/800/1*gzFp0uHx_DmG-b97j1t8UQ.png "benchmark")

```golang
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)
	}
}

```


[Medium Article](https://medium.com/@manigandand/list-files-in-a-directory-using-golang-963b1df11304)