Golang: Walk Directory, List Files

By Xah Lee. Date: . Last updated: .

Golang has 3 different functions to walk a directory.

path/filepath.Walk
introduced in go version 1.

https://pkg.go.dev/path/filepath#Walk

Slow. Don't use this. For example, see Golang: path/filepath.Walk

path/filepath.WalkDir
new in go version 1.16. [see Golang: Version History Release Dates]

https://pkg.go.dev/path/filepath#WalkDir

I recommend using this.

os/fs.WalkDir
new in go version 1.16, part of the new abstract file system.

here's how to use filepath.WalkDir from package "path/filepath"

to go thru all files and directory, use

filepath.WalkDir(dirPath, doF)

it walks dirPath, for each file or dir, it calls doF

doF is a function of type fs.WalkDirFunc you need to define. It do something for each file.

the doF Function (type WalkFunc)

The spec for type WalkFunc is this:

var doF = func(xpath string, xinfo fs.DirEntry, xerr error) error {}

The arguments passed to the doF are:

xpath (type string)
the full path of current file or directory.
xinfo (type fs.DirEntry)
A fs.DirEntry object. It contain info about the file.

e.g. use it like this: xinfo.IsDir().

https://pkg.go.dev/io/fs#FileInfo

xerr (type error)
If there's a error.

https://pkg.go.dev/path/filepath#WalkFunc

Return Value of Process File Function

When there's a problem, a error is passed to doF. The function doF can do whatever with it.

doF must return one of:

nil
Normal.
filepath.SkipDir
If doF returns filepath.SkipDir, then filepath.WalkDir will skip it. Meaning: If current path is dir, skip it, but if current path is a file, then skip rest of files in the directory
value of type error
(error is a interface) If doF returns a error, then filepath.WalkDir returns a error. The walk is stopped

Sample Code to Walk a Dir

package main

import (
	"fmt"
	"io/fs"
	"path/filepath"
)

var xDir = "c:/Users/xah/web/xahlee_info/js/"

// go thru a dir and print all file name and extension

func main() {

	var doF = func(xpath string, xinfo fs.DirEntry, xerr error) error {

		// first thing to do, check error. and decide what to do about it
		if xerr != nil {
			fmt.Printf("error [%v] at a path [%q]\n", xerr, xpath)
			return xerr
		}

		fmt.Printf("xpath: %v\n", xpath)

		// find out if it's a dir or file, if file, print info
		if xinfo.IsDir() {
			fmt.Printf("is dir.\n")
		} else {
			fmt.Printf("  dir: [%v]\n", filepath.Dir(xpath))
			fmt.Printf("  file name [%v]\n", xinfo.Name())
			fmt.Printf("  extenion: [%v]\n", filepath.Ext(xpath))
		}

		return nil
	}

	err := filepath.WalkDir(xDir, doF)

	if err != nil {
		fmt.Printf("error walking the path %q: %v\n", xDir, err)
	}
}

Migration tip from filepath.Walk to filepath.WalkDir

Golang

Compile and Run

String

Types and Values

Branching and Loop

Data Structure

Function

Misc

Examples

Reference