C# – How to search for files in a directory

You can use Directory.EnumerateFiles() (in System.IO) to search for files in a directory. This has many overloads, allowing you to specify exactly what you want. You can get all the files in a directory, get all files in all subdirectories, filter files by name (including extension), and filter by attributes.

Here’s an example of getting all top-level files in a directory:

using System.IO; foreach (var file in Directory.EnumerateFiles(@"C:\temp\records\")) { Console.WriteLine(file); }
Code language: C# (cs)

This outputs the full file paths from the top-level directory:

C:\temp\records\animals.txt C:\temp\records\b.txt C:\temp\records\hello.txt C:\temp\records\words.txt
Code language: plaintext (plaintext)

In this article, I’ll show how to use Directory.EnumerateFiles() to search for files in different scenarios.

Search the root directory and all subdirectories

You can use SearchOption.AllDirectories to search for files in the root directory and all of its subdirectories. It does a breadth-first search, returning all files from the root directory, then files from the next level down, and so on.

Here’s an example of using Directory.EnumerateFiles() with SearchOption.AllDirectories:

using System.IO; foreach (var file in Directory.EnumerateFiles(@"C:\temp\records\", "*", SearchOption.AllDirectories)) { Console.WriteLine(file); }
Code language: C# (cs)

Note: “*” means include all files in the search.

This outputs the full file paths in breadth-first order:

C:\temp\records\Code Snippets.txt C:\temp\records\books\Antifragile.txt C:\temp\records\books\Code Complete.txt C:\temp\records\movies\Happy Gilmore.txt C:\temp\records\movies\Jurassic Park.txt
Code language: plaintext (plaintext)

Your other option is to use EnumerationOptions.RecurseSubdirectories. Use this if you’re already using EnumerationOptions to control some other setting (such as filtering by file attributes). Here’s an example of how to use this:

using System.IO; var options = new EnumerationOptions() { RecurseSubdirectories = true, //some other setting }; foreach (var file in Directory.EnumerateFiles(@"C:\temp\records\", "*", options)) { Console.WriteLine(file); }
Code language: C# (cs)

This has the same exact results as the example above using SearchOption.AllDirectories.

Filter by file name or extension

You can provide a search pattern to filter files by name or extension. This lets you do exact or partial matches by using the wildcard character (*).

Here’s an example of searching for files that match the name exactly:

using System.IO; foreach (var file in Directory.EnumerateFiles(@"C:\temp\records\", searchPattern: "code snippets.txt")) { Console.WriteLine(file); }
Code language: C# (cs)

This outputs the full file path for the “code snippets.txt” file:

C:\temp\records\code snippets.txt
Code language: plaintext (plaintext)

Here’s an example of searching for all JSON files (ones that have a .json file extension):

using System.IO; foreach (var file in Directory.EnumerateFiles(@"C:\temp\records\", searchPattern: "*.json")) { Console.WriteLine(file); }
Code language: C# (cs)

This outputs the full file path of the only JSON file:

C:\temp\records\config.json
Code language: plaintext (plaintext)

Note: Directory.EnumerateFiles() searches for all files by default. So you only need to pass in “*” to get all files if you are using one of the method overloads that uses all of the parameters, such as EnumerateFiles(path, searchPattern, searchOption).

File name case sensitivity

Directory.EnumerateFiles() uses the current platform’s case sensitivity settings by default. On Windows, that means it does a case-insensitive file name search. You can control the case sensitivity settings by using EnumerationOptions.MatchCasing.

Here’s an example of doing a case-sensitive search for files that end in “.CSV”:

using System.IO; var options = new EnumerationOptions() { MatchCasing = MatchCasing.CaseSensitive }; foreach (var file in Directory.EnumerateFiles(@"C:\temp\records\", "*.CSV", options)) { Console.WriteLine(file); }
Code language: C# (cs)

This outputs the following (notice the extension is exactly “.CSV”):

C:\temp\records\recipes.CSV
Code language: plaintext (plaintext)

Filter by a file attribute

Use EnumerationOptions.AttributesToSkip to filter files based on attributes. For example, the following searches for all files, filtering out ones that are read-only:

using System.IO; var options = new EnumerationOptions() { AttributesToSkip = FileAttributes.ReadOnly }; foreach (var file in Directory.EnumerateFiles(@"C:\temp\records\", "*", options)) { Console.WriteLine(file); }
Code language: C# (cs)

This outputs the full file paths for all writable (not read-only) files:

C:\temp\records\config.json
Code language: plaintext (plaintext)

AttributesToSkip is an enum flag, so you can bitwise OR all the attributes that you want to filter out. For example, let’s say you want to filter out hidden files and read-only files. Here’s how you’d do that:

new EnumerationOptions() { AttributesToSkip = FileAttributes.ReadOnly | FileAttributes.Hidden }
Code language: C# (cs)

Leave a Comment