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:
Code language: plaintext (plaintext)C:\temp\records\animals.txt C:\temp\records\b.txt C:\temp\records\hello.txt C:\temp\records\words.txt
In this article, I’ll show how to use Directory.EnumerateFiles() to search for files in different scenarios.
Table of Contents
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:
Code language: plaintext (plaintext)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
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:
Code language: plaintext (plaintext)C:\temp\records\code snippets.txt
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:
Code language: plaintext (plaintext)C:\temp\records\config.json
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”):
Code language: plaintext (plaintext)C:\temp\records\recipes.CSV
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:
Code language: plaintext (plaintext)C:\temp\records\config.json
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)