C# list directory
last modified October 16, 2026
In this article we show how to list directory contents in C#. We list files and directories and filter the output based on the file name pattern, file extension, file size, modification date, or content.
Directory definition
A directory, also called a folder, is a location for storing files on a computer. In addition to files, a directory also stores other directories or links.
In C# we can use Directory or DirectoryInfo to work
with directories. Directory is a static class that provides static
methods for working with directories. An instance of DirectoryInfo
provides information about a specific directory. Its methods return
FileInfo and DirectoryInfo objects, which give us
access to the size, dates, and attributes of the entries. The classes are
available in the System.IO namespace.
The methods return either an enumerable collection (e.g.
Directory.EnumerateFiles) or an array of values
(e.g. Directory.GetFiles). When we use a method that returns an
array, we must wait for the whole array to be returned, while with the
enumerable collection, we can process the data right away. Working with
enumerable collections is more efficient and takes less memory, especially for
large directory trees.
The order in which the entries are returned is not guaranteed; it depends on the file system. Therefore, we sort the results in our examples.
Example directory
In the examples, we use the following data directory, which is
located in the project directory.
data ├── 2025 │ ├── old │ │ └── archive.pdf │ ├── q1_data.csv │ └── summary.txt ├── books │ ├── marathon.txt │ └── thermopylae.txt ├── images │ ├── logo.png │ └── photo.jpg ├── notes.md ├── report.txt └── sales.csv
C# DirectoryInfo.EnumerateDirectories
The DirectoryInfo.EnumerateDirectories method returns an
enumerable collection of directory information for the specified directory.
var dirInfo = new DirectoryInfo("data");
var options = new EnumerationOptions { RecurseSubdirectories = true };
foreach (var dir in dirInfo.EnumerateDirectories("*", options).OrderBy(d => d.FullName))
{
Console.WriteLine(Path.GetRelativePath(".", dir.FullName));
}
In the example, we recursively find all directories in the chosen directory.
var options = new EnumerationOptions { RecurseSubdirectories = true };
The EnumerationOptions class controls the enumeration. With
RecurseSubdirectories, the subdirectories are searched too.
Console.WriteLine(Path.GetRelativePath(".", dir.FullName));
The FullName property contains the absolute path. We print the
path relative to the current directory.
$ dotnet run data/2025 data/2025/old data/books data/images
C# Directory.GetDirectories and GetFiles
The Directory.GetDirectories and Directory.GetFiles
methods return the names of subdirectories and files as string arrays. Without
a search option, only the top level of the directory is listed.
string[] dirs = Directory.GetDirectories("data");
string[] files = Directory.GetFiles("data");
Console.WriteLine("Directories:");
foreach (var dir in dirs.Order())
{
Console.WriteLine($" {dir}");
}
Console.WriteLine("Files:");
foreach (var file in files.Order())
{
Console.WriteLine($" {file}");
}
The example lists the top-level subdirectories and files of the
data directory. The returned names include the path that we passed
to the methods.
$ dotnet run Directories: data/2025 data/books data/images Files: data/notes.md data/report.txt data/sales.csv
C# Directory.EnumerateFiles search pattern
The second parameter of the EnumerateFiles, GetFiles,
and similar methods is a search pattern. The * wildcard matches
zero or more characters and the ? wildcard matches exactly one
character. The SearchOption.AllDirectories option searches
recursively.
var files = Directory.EnumerateFiles("data", "*.csv", SearchOption.AllDirectories);
foreach (var file in files.Order())
{
Console.WriteLine(file);
}
The example recursively lists all CSV files.
$ dotnet run data/2025/q1_data.csv data/sales.csv
C# list files with multiple extensions
A search pattern can contain only one extension. To search for several extensions, we filter the files with LINQ.
var extensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
".csv", ".txt", ".pdf"
};
var files = Directory.EnumerateFiles("data", "*", SearchOption.AllDirectories)
.Where(f => extensions.Contains(Path.GetExtension(f)))
.Order()
.ToList();
foreach (var file in files)
{
Console.WriteLine(file);
}
Console.WriteLine($"{files.Count} files found");
The example recursively searches for CSV, TXT, and PDF files. The extensions are
stored in a case-insensitive set, so that files such as REPORT.TXT
are found too.
.ToList();
We materialize the query into a list. Otherwise, the directory tree would be searched twice: once in the loop and once when counting the files.
$ dotnet run data/2025/old/archive.pdf data/2025/q1_data.csv data/2025/summary.txt data/books/marathon.txt data/books/thermopylae.txt data/report.txt data/sales.csv 7 files found
C# list files by file name
In the following example, we list files whose names contain a given word.
var files = from file in Directory.EnumerateFiles("data", "*", SearchOption.AllDirectories)
where Path.GetFileName(file).Contains("data", StringComparison.OrdinalIgnoreCase)
select file;
foreach (var file in files)
{
Console.WriteLine(file);
}
The example searches recursively for files whose file name, the last part of
the path, contains the word data. The directory name data in the
path is not taken into account.
$ dotnet run data/2025/q1_data.csv
C# list files by size
The DirectoryInfo.EnumerateFiles method returns
FileInfo objects. The Length property of a
FileInfo gives us the size of a file.
long limit = 10 * 1024;
var dirInfo = new DirectoryInfo("data");
var files = from fi in dirInfo.EnumerateFiles("*", SearchOption.AllDirectories)
where fi.Length > limit
orderby fi.Length descending
select fi;
foreach (var fi in files)
{
Console.WriteLine($"{fi.Name,-14} {fi.Length,8:N0} bytes");
}
The example finds all files larger than 10 KB and sorts them by size in descending order.
$ dotnet run photo.jpg 480,000 bytes archive.pdf 250,000 bytes q1_data.csv 15,360 bytes logo.png 12,000 bytes
C# list files by date
The FileInfo class has properties for the creation, last write,
and last access times of a file.
var dateLimit = new DateTime(2025, 1, 1);
var dirInfo = new DirectoryInfo("data");
var files = from fi in dirInfo.EnumerateFiles("*", SearchOption.AllDirectories)
where fi.LastWriteTime < dateLimit
orderby fi.LastWriteTime
select fi;
foreach (var fi in files)
{
Console.WriteLine($"{fi.Name,-12} {fi.LastWriteTime:yyyy-MM-dd}");
}
In the example, we list all files that were last modified before 2025. We use the last write time, because the creation time is not reliably available on all file systems.
$ dotnet run archive.pdf 2023-03-14 logo.png 2024-06-20 notes.md 2024-11-02
C# search file content
In the following example, we list the lines of text files that contain a given word.
var lines = from file in Directory.EnumerateFiles("data/books", "*.txt")
from line in File.ReadLines(file)
where line.Contains("Persian")
orderby file
select new { File = Path.GetFileName(file), Line = line };
foreach (var e in lines)
{
Console.WriteLine($"{e.File}: {e.Line}");
}
The two from clauses go over all lines of all text files in the
books directory. The File.ReadLines method reads the
files lazily, line by line.
$ dotnet run marathon.txt: The Battle of Marathon took place in 490 BC during the first Persian invasion marathon.txt: and a Persian force commanded by Datis and Artaphernes. thermopylae.txt: led by King Leonidas of Sparta, and the Persian Empire of Xerxes I over the thermopylae.txt: course of three days, during the second Persian invasion of Greece.
C# directory size
In the following example, we determine the size of a directory.
var dirInfo = new DirectoryInfo("data");
long size = dirInfo.EnumerateFiles("*", SearchOption.AllDirectories)
.Sum(fi => fi.Length);
Console.WriteLine($"The directory size: {size:N0} bytes");
We go over all files in the directory and its subdirectories and sum their sizes.
$ dotnet run The directory size: 768,860 bytes
C# EnumerationOptions
The EnumerationOptions class provides more control than
SearchOption. We can limit the depth of the recursion, set the case
sensitivity of the search pattern, or skip entries with certain attributes. By
default, it also skips files and directories that we do not have permission to
access; with SearchOption.AllDirectories, such an entry throws an
UnauthorizedAccessException and stops the whole enumeration.
var options = new EnumerationOptions
{
RecurseSubdirectories = true,
MaxRecursionDepth = 1,
MatchCasing = MatchCasing.CaseInsensitive,
IgnoreInaccessible = true
};
foreach (var file in Directory.EnumerateFiles("data", "*.TXT", options).Order())
{
Console.WriteLine(file);
}
We search for text files with a case-insensitive pattern. The search goes only
one level deep; the files in data/2025/old would not be found.
$ dotnet run data/2025/summary.txt data/books/marathon.txt data/books/thermopylae.txt data/report.txt
Source
How to enumerate directories and files
In this article we have shown how to list directories in C#.
Author
List all C# tutorials.