Collecting Data while walkng a filesystem with Go
There are several ways to use fs.WalkDir
to collect data.
Basic fs.WalkDir
⌗
Here’s a relatively simple WalkDir to print all paths that start with “magic/”.
func ImportantBusinessFunc(fsys fs.FS) (error) {
err := fs.WalkDir(fsys, ".", func(path string, dir fs.DirEntry, err error) error {
if err != nil {
return err
}
if !strings.HasPrefix(path, "magic/") {
return nil
}
fmt.Println(path)
return nil
})
}
This doesn’t help because I want to collect those paths, not just print them out.
Add Collector Slice⌗
Assemble data by instantiating a collector that we can add to as we walk.
(WalkDir is not concurrent.)
func ImportantBusinessFunc(fsys fs.FS) ([]string, error) {
s := []string{}
err := fs.WalkDir(fsys, ".", func(path string, dir fs.DirEntry, err error) error {
if err != nil {
return err
}
if !strings.HasPrefix(path, "magic/") {
return nil
}
s = append(s, path)
return nil
})
return s, err
}
The function passed as a parameter to fs.WalkDir
is a closure, and lexical scoping
means variables defined in ImportantBusinessFunc are available inside contained closures.
Pointer to a Collection⌗
Suppose we want the file walking to be more reusable?
func ImportantBusinessFunc(fsys fs.FS) ([]string, error) {
s := []string{}
err := _importantBusiness(fsys, &s, "magic/")
return s, err
}
func _importantBusiness(fsys fs.FS, collector *[]string, needle string) error {
return fs.WalkDir(fsys, ".", func(path string, dir fs.DirEntry, err error) error {
if err != nil {
return err
}
if !strings.HasPrefix(path, needle) {
return nil
}
*collector = append(*collector, path)
return nil
})
}
Read other posts