Read Directory Contents With Zig

Learn how to read the contents of a directory in Zig using the page allocator.

Efficiently Reading Directory Contents in Zig with a Page Allocator

Hey there welcome back to my Zig series, the language that I've been using a lot lately for my hobby projects. It's a language that keeps evolving and I'm excited to share more about it with you. I personally find it an absolute joy to work with and hope I can awake some interest in you the reader as well and perhaps even turn you to the zig side.

In this article, we'll check out how to read the contents of a directory in Zig, the zig way by using allocators. For our purposes we'll be using the std.heap.page_allocator which is the most basic allocator that zig comes with. We could further optimize this if we wanted to also allow recursive directory reading, but for now we'll keep it simple.

Understanding the Basics of Directory Management

Before we jump into the code, let’s clarify what we’re trying to achieve. Directories are foundational to file systems. They allow us to organize files hierarchically, making it easier to navigate and manage data. When working with file systems, you'll often need to read the contents of a directory for tasks like file management, data processing, displaying a list of files to the user, or for your various CLI programs that you might be writing.

The Power of Zig

Zig stands out among modern programming languages due to its simplicity and low-level control. With explicit memory management and a focus on safety and performance, Zig provides developers the tools needed for efficient system programming. The language allows for direct interaction with the file system, making it an excellent choice for tasks like reading directory contents.

The Code

This is the complete code block with comments on how to read the contents of a directory in Zig using the page allocator.

const std = @import("std");

pub fn main() !void {
    // Define the allocator
    const allocator = std.heap.page_allocator; 

    // Open the current working directory as an iterable directory
    var dir = try std.fs.cwd().openIterableDir(".", .{});
    defer dir.close();

    // Create an ArrayList to hold the file names
    var file_list = std.ArrayList([]const u8).init(allocator);
    defer file_list.deinit();

    // Iterate through the directory contents
    var dirIterator = dir.iterate();
    while (try dirIterator.next()) |dirContent| {
        // Append the file name to the ArrayList
        try file_list.append(dirContent.name);
    }

    // Print the contents of the ArrayList
    const stdout = std.io.getStdOut().writer();
    for (file_list.items) |file_name| {
        try stdout.print("File: {s}\n", .{file_name});
    }
}

Now let's break down the code:

  1. At the very tippy top we define the allocator we want to use, in this case the page allocator.

  2. We then open the current working directory as an iterable directory. the openIterableDir function takes in two parameters, the first is subDir which like the name suggests allows you to open a subdirectory of the current working directory, and the second is a set of flags which we are not using in this case.

  3. We then create an ArrayList to hold the file names, this is a dynamic array that can grow and shrink as needed.

  4. We use the allocator to initialize the ArrayList and then defer the deinit function to free the memory when the function exits.

  5. We then iterate through the directory contents using the dirIterator and append the file names to the ArrayList.

  6. Finally, we print the contents of the ArrayList to the standard output.

And that's it! You've successfully read the contents of a directory in Zig using the page allocator.

if you wish to learn more about the page allocator or any other allocator that zig comes with, feel free to check out my article on Zig Allocators Explained.

Conclusion

Thank you for taking your time and reading the article till the end. I hope you've learnt something new and exciting and that you may consider using or learning Zig in the future. If you have any questions or feedback feel free to reach out to me on Twitter.