EDIT FOR 1.16: Enough people still hit this answer, that I thought I'd update it for Go 1.16.
The function filepath.WalkDir introduced in Go 1.16 has better performance than filepath.Walk mentioned in the previous edit. Here's a working example:
EDIT: Enough people still hit this answer, that I thought I'd update it for the Go1 API. This is a working example of filepath.Walk(). The original is below.
Here is an example to loop through all files and directories recursively. Note that if you want to know whether the path you're appending is a directory just check "f.IsDir()".
Note that "Walk does not follow symbolic links" so if you are looking to write a function that does that I recommend ioutil.ReadDir. My own benchmark test showed that it is faster and less memory intensive than filepath.Glob.
Additionally, ioutil.ReadDir is sorting files by basename using basic string comparison (strA > strB). As a devops guy, I generally sort dir names by doing a reverse numerical comparison (latest build first for example). If that is also your case then it is better to call os.ReadDir directly (ioutil.ReadDir is calling this under the covers) and do the sorting yourself.
Here is an example of the ReadDir part with Numerical sort:
// ReadDirNumSort - Same as ioutil/ReadDir but uses returns a Numerically
// Sorted file list.
//
// Taken from https://golang.org/src/io/ioutil/ioutil.go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// Modified Sort method to use Numerically sorted names instead.
// It also allows reverse sorting.
func ReadDirNumSort(dirname string, reverse bool) ([]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
}
if reverse {
sort.Sort(sort.Reverse(byName(list)))
} else {
sort.Sort(byName(list))
}
return list, nil
}
// byName implements sort.Interface.
type byName []os.FileInfo
func (f byName) Len() int { return len(f) }
func (f byName) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
func (f byName) Less(i, j int) bool {
nai, err := strconv.Atoi(f[i].Name())
if err != nil {
return f[i].Name() < f[j].Name()
}
naj, err := strconv.Atoi(f[j].Name())
if err != nil {
return f[i].Name() < f[j].Name()
}
return nai < naj
}
Go standard package ioutil has built in function for this case scenario see below example
func searchFiles(dir string) { // dir is the parent directory you what to search
files, err := ioutil.ReadDir(dir)
if err != nil {
log.Fatal(err)
}
for _, file := range files {
fmt.Println(file.Name())
}
}