Go

List directory in Go

25 September 2026 · 5 min read

List directory in Go

Go, renowned for its efficiency and concurrency features, offers robust tools for interacting with the file system. One common task is listing directory contents, crucial for file management, backups, and various other operations. Mastering directory listing in Go empowers developers to build powerful and versatile applications. This post will delve into the intricacies of listing directories in Go, exploring various methods, best practices, and real-world examples to help you effectively manage file system interactions within your Go projects.

Using the os Package for Basic Directory Listing

The core os package in Go provides the foundation for interacting with the operating system, including file system operations. The os.ReadDir function is the primary tool for listing directory contents. It returns a slice of os.DirEntry structs, each representing a file or subdirectory within the target directory.

Here’s a simple example:

package main import ( "fmt" "os" ) func main() { files, err := os.ReadDir(".") // Lists the current directory if err != nil { panic(err) } for _, file := range files { fmt.Println(file.Name()) } } 

This code snippet retrieves the contents of the current directory and prints the name of each entry. Error handling is crucial when working with file system operations, as unexpected issues like permissions errors can occur.

Filtering Directory Contents

Often, you need to filter the listed entries based on specific criteria, such as file type or name patterns. Go offers flexible ways to achieve this using the filepath package in conjunction with os.ReadDir.

For instance, to list only files ending with “.txt”:

package main import ( "fmt" "os" "path/filepath" ) func main() { files, err := os.ReadDir(".") if err != nil { panic(err) } for _, file := range files { if filepath.Ext(file.Name()) == ".txt" { fmt.Println(file.Name()) } } } 

This example uses filepath.Ext to extract the file extension and filter accordingly. The filepath package offers a range of other functions for manipulating and analyzing file paths, providing granular control over filtering logic.

Handling Subdirectories Recursively

When dealing with nested directory structures, you’ll often need to list files recursively. While os.ReadDir lists only the immediate contents of a directory, you can implement recursive listing using a function that calls itself when encountering a subdirectory.

package main import ( "fmt" "os" "path/filepath" ) func listFilesRecursive(dir string) error { entries, err := os.ReadDir(dir) if err != nil { return err // Handle errors appropriately } for _, entry := range entries { fullPath := filepath.Join(dir, entry.Name()) fmt.Println(fullPath) // Process each file or directory if entry.IsDir() { // If a subdirectory is found err := listFilesRecursive(fullPath) if err != nil { return err } } } return nil } func main() { err := listFilesRecursive(".") if err != nil { fmt.Println("Error:", err) } } 

This recursive function traverses the directory structure, printing the full path of each file and directory it encounters. Remember that with recursion, proper base cases (conditions to stop the recursion) are essential to avoid infinite loops.

Performance Considerations

When working with large directories, performance becomes a critical factor. The os.ReadDir function reads the entire directory contents into memory. For extremely large directories, this can lead to memory issues. Consider alternative approaches like filepath.WalkDir which processes entries one at a time, improving efficiency for very large directory structures.

For example:

package main import ( "fmt" "os" "path/filepath" ) func main() { filepath.WalkDir(".", func(path string, d os.DirEntry, err error) error { if err != nil { return err } fmt.Println(path) return nil }) } 

Here, filepath.WalkDir processes each directory entry individually, reducing memory consumption for large directories. This approach provides a more memory-efficient solution for large directory trees.

[Infographic Placeholder: Visual representation of os.ReadDir vs. filepath.WalkDir memory usage]

Frequently Asked Questions

Q: How can I sort the listed directory entries?

A: You can sort the slice of os.DirEntry returned by os.ReadDir using the sort package in Go. This allows you to sort by name, size, modification time, or other criteria.

Efficiently listing and managing directory contents is fundamental to many Go applications. By understanding the tools and techniques presented here—from basic listing with os.ReadDir to recursive traversal and performance optimization with filepath.WalkDir—you can confidently handle diverse file system operations within your Go projects. Explore further by using this helpful resource and other authoritative sources like the official Go documentation and community forums to enhance your file system management skills. This knowledge will undoubtedly prove invaluable as you develop more sophisticated and robust applications.

Question & Answer :
I’ve been trying to figure out how to simply list the files and folders in a single directory in Go.

I’ve found filepath.Walk, but it goes into sub-directories automatically, which I don’t want. All of my other searches haven’t turned anything better up.

I’m sure that this functionality exists, but it’s been really hard to find. Let me know if anyone knows where I should look. Thanks.

You can try using the ReadDir function in the os package. Per the docs:

ReadDir reads the named directory, returning all its directory entries sorted by filename.

The resulting slice contains os.DirEntry types, which provide the methods listed here. Here is a basic example that lists the name of everything in the current directory (folders are included but not specially marked - you can check if an item is a folder by using the IsDir() method):

package main import ( "fmt" "os" "log" ) func main() { entries, err := os.ReadDir("./") if err != nil { log.Fatal(err) } for _, e := range entries { fmt.Println(e.Name()) } }