I am working to recursively iterate through a given directory and store the name of files found and their sizes in a map[string]uint32
. I've found a post describing how to recursively walk a specified directory using the path/filepath/WalkDir function and a WalkDirFunc.
I am relatively new to Go, and haven't been able to find a way to pass a reference to my map to the WalkDirFunc
since its signature specifies three parameters only:
func main() {
args := os.Args
if len(args) != 2 {
msg := fmt.Sprintf("Usage: %v <path_to_directory>", args[0])
log.Fatal(msg)
}
fullPath := args[1]
dirMap := make(map[string]uint32)
filepath.WalkDir(fullPath, walk)
}
// how to create parameter accepting &map[string]uint32
func walk(path string, entry fs.DirEntry, err error) error {
if err != nil {
return err
}
if !entry.IsDir() {
// add entry and it's size to dirMap
file, err := os.Stat(path)
if err != nil {
log.Println("Error determining file size:", err)
}
size := file.Size()
// add path and size to dirMap
} else if entry.IsDir() {
// recurse here
} else {
log.Println("Unhandled branch:")
log.Println(entry.Info())
}
return nil
}
EDIT: Since walk
is a WalkDirFunc
passed to filepath.walkDir
, it is necessary to pass the map beginning here. In Python, I would use named parameters to accomplish this, but what is the best way in Go?
func main() {
args := os.Args
...
fullPath := args[1]
dirMap := make(map[string]uint32)
// dirMap should be passed here
filepath.WalkDir(fullPath, walk)
}
CodePudding user response:
Use a closure. Change walk to:
func walk(dirMap map[string]uint32, path string, entry fs.DirEntry, err error) error {
...
}
Call WalkDir like this:
dirMap := make(map[string]uint32)
filepath.WalkDir(fullPath, func(path string, entry fs.DirEntry, err error) error {
return walk(dirMap, path, entry, err)
})
Run the example here: https://go.dev/play/p/rjV2rSBsUDz