C#
Directory.EnumerateFiles
Directory.GetFiles
File System
.NET

What is the difference between Directory.EnumerateFiles vs Directory.GetFiles?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Directory.EnumerateFiles and Directory.GetFiles both return file paths from the file system, but they behave differently enough that the choice matters in real code. The short version is simple: GetFiles materializes everything first, while EnumerateFiles streams results as you iterate. That affects memory usage, latency, and even when exceptions appear.

GetFiles Builds the Full Array Up Front

Directory.GetFiles returns a string[]. To do that, .NET has to collect all matching file names before it hands control back to your code.

csharp
1using System;
2using System.IO;
3
4string[] files = Directory.GetFiles("/tmp", "*.log");
5Console.WriteLine(files.Length);

This is convenient when you truly need the whole list in memory, such as when you need indexed access or you know the directory is small.

The tradeoff is that you wait for the full scan to finish before you can process the first file.

EnumerateFiles Streams Results Lazily

Directory.EnumerateFiles returns IEnumerable<string>. That means iteration begins before the entire directory scan has been materialized.

csharp
1using System;
2using System.IO;
3
4foreach (var file in Directory.EnumerateFiles("/tmp", "*.log"))
5{
6    Console.WriteLine(file);
7    break;
8}

This often reduces startup latency because your code can begin processing the first result immediately.

It also usually reduces memory pressure when the directory contains many files.

Why the Difference Matters on Large Directories

If a directory contains ten files, both methods may feel identical. If it contains hundreds of thousands, the distinction becomes important.

With GetFiles:

  • all file names are gathered before processing starts
  • memory usage grows with the full result set
  • the caller waits longer before seeing the first item

With EnumerateFiles:

  • results arrive incrementally
  • processing can overlap with enumeration
  • you can stop early without materializing the rest of the directory

That last point is especially useful for search tasks where you only need the first matching file.

Exception Timing Is Different Too

Because GetFiles evaluates eagerly, errors often show up at the method call itself. With EnumerateFiles, some exceptions may appear later during enumeration because the work is happening lazily.

That means code structure matters.

csharp
1using System;
2using System.IO;
3
4try
5{
6    foreach (var file in Directory.EnumerateFiles("/restricted"))
7    {
8        Console.WriteLine(file);
9    }
10}
11catch (UnauthorizedAccessException ex)
12{
13    Console.WriteLine(ex.Message);
14}

If you switch from GetFiles to EnumerateFiles, keep the try block around the iteration, not just around the method call.

Prefer EnumerateFiles for Streaming Workloads

EnumerateFiles is usually the better default when you want to process files one by one.

Examples include:

  • computing hashes
  • scanning log files
  • copying or archiving matches
  • searching until a condition is met
  • feeding file paths into a pipeline

This pattern avoids building a huge in-memory array that you never actually need.

Prefer GetFiles When You Need a Snapshot Array

GetFiles still has valid uses.

It can be the right choice when:

  • you need the full list immediately
  • you need random indexed access
  • you want to sort the full results in memory anyway
  • the directory is small enough that eager materialization is irrelevant

In those cases, the simplicity of an array can be worth the eager cost.

The Same Idea Applies to Directories and File System Entries

This difference is not unique to files. .NET follows the same pattern with EnumerateDirectories, GetDirectories, EnumerateFileSystemEntries, and GetFileSystemEntries.

Once you understand eager versus lazy enumeration, the rest of the API family becomes easier to choose correctly.

Common Pitfalls

  • Using GetFiles on very large directories and then wondering why memory spikes.
  • Using EnumerateFiles but placing exception handling around the method call instead of the iteration.
  • Materializing EnumerateFiles(...).ToList() immediately and losing the main benefit of streaming.
  • Assuming the two methods differ only in return type rather than in execution behavior.
  • Forgetting that either method can still be expensive if recursive search touches a very large tree.

Summary

  • 'GetFiles returns a fully materialized array of file paths.'
  • 'EnumerateFiles returns file paths lazily as you iterate.'
  • 'EnumerateFiles is usually better for large directories and streaming workflows.'
  • 'GetFiles is fine when you genuinely need the full list at once.'
  • The choice affects memory use, latency, and where exceptions surface.

Course illustration
Course illustration

All Rights Reserved.