go file dir walk
原文链接: go file dir walk
递归遍历
// We use a counting semaphore to limit
// the number of parallel calls to ReadDir.
sema := make(chan bool, 20)
func allPackages(ctxt *build.Context, sema chan bool, root string, ch chan<- item) {
root = filepath.Clean(root) + string(os.PathSeparator)
var wg sync.WaitGroup
var walkDir func(dir string)
walkDir = func(dir string) {
// Avoid .foo, _foo, and testdata directory trees.
base := filepath.Base(dir)
if base == "" || base[0] == '.' || base[0] == '_' || base == "testdata" {
return
}
for _, ignoredFolder := range ignoreFolders {
if base == ignoredFolder {
return
}
}
pkg := filepath.ToSlash(strings.TrimPrefix(dir, root))
// Prune search if we encounter any of these import paths.
switch pkg {
case "builtin":
return
}
sema <- true
files, err := ioutil.ReadDir(dir)
<-sema
if err == nil {
ch <- item{pkg, err}
}
for _, fi := range files {
fi := fi
if fi.IsDir() {
wg.Add(1)
go func() {
walkDir(filepath.Join(dir, fi.Name()))
wg.Done()
}()
}
}
}
walkDir(root)
wg.Wait()
}
func search(ctx context.Context, root string, pattern string) ([]string, error) {
g, ctx := errgroup.WithContext(ctx)
paths := make(chan string, 100)
// get all the paths
g.Go(func() error {
defer close(paths)
return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.Mode().IsRegular() {
return nil
}
// if !info.IsDir() && !strings.HasSuffix(info.Name(), ".go") {
// return nil
// }
select {
case paths <- path:
case <-ctx.Done():
return ctx.Err()
}
return nil
})
})
c := make(chan string, 100)
for path := range paths {
p := path
g.Go(func() error {
data, err := ioutil.ReadFile(p)
if err != nil {
return err
}
if !bytes.Contains(data, []byte(pattern)) {
return nil
}
select {
case c <- p:
println(p)
case <-ctx.Done():
return ctx.Err()
}
return nil
})
}
go func() {
g.Wait()
close(c)
}()
var m []string
for r := range c {
m = append(m, r)
}
return m, g.Wait()
}
GoLang 遍历目录,一个常用的功能。
package main
import (
"path/filepath"
"os"
"fmt"
"flag"
)
func getFilelist(path string) {
err := filepath.Walk(path, func(path string, f os.FileInfo, err error) error {
if ( f == nil ) {return err}
if f.IsDir() {return nil}
println(path)
return nil
})
if err != nil {
fmt.Printf("filepath.Walk() returned %v\n", err)
}
}
func main(){
flag.Parse()
root := flag.Arg(0)
getFilelist(root)
}
下面这个只列出当前文件夹下的文件:
package main
import "io/ioutil"
func listAll(path string) {
files, _ := ioutil.ReadDir(path)
for _, fi := range files {
if fi.IsDir() {
//listAll(path + "/" + fi.Name())
println(path + "/" + fi.Name())
} else {
println(path + "/" + fi.Name())
}
}
}
func main() {
listAll(".")
}
另一个版本:
package main
import (
"flag"
"fmt"
"os"
"path/filepath"
)
func walkpath(path string, f os.FileInfo, err error) error {
fmt.Printf("%s with %d bytes\n", path, f.Size())
return nil
}
func main() {
flag.Parse()
root := flag.Arg(0) // 1st argument is the directory location
fmt.Println(root)
filepath.Walk("./", walkpath)
}
版本 4:
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() ([]string, error) {
searchDir := "c:/path/to/dir"
fileList := []string{}
err := filepath.Walk(searchDir, func(path string, f os.FileInfo, err error) error {
fileList = append(fileList, path)
return nil
})
for _, file := range fileList {
fmt.Println(file)
}
}