C# & ADO.NET

Export a folder's file list to CSV or Excel in C#

C# & ADO.NET · · Published 2026-09-13

An inventory of files, with names, sizes and dates, is a common request from people who want to sort and filter it in Excel. DirectoryInfo gives you the data; writing a CSV that Excel opens without mangling accents or dates takes a few precautions.

Collect the data

using System.IO;
using System.Linq;

var root = new DirectoryInfo(@"D:\Shared\Projects");
var files = root.EnumerateFiles("*", SearchOption.AllDirectories)
    .Select(f => new
    {
        Folder = Path.GetRelativePath(root.FullName, f.DirectoryName), // .NET Core 2.0+; see note
        f.Name,
        f.Extension,
        f.Length,
        f.LastWriteTimeUtc
    })
    .ToList();

Path.GetRelativePath does not exist on .NET Framework; there, use f.DirectoryName.Substring(root.FullName.Length).TrimStart('\\'). If some subfolders are unreadable, use the safe enumeration shown in List files recursively.

Write CSV

using System.Globalization;
using System.Text;

static string Q(string s) =>
    s.IndexOfAny(new[] { ',', '"', '\r', '\n' }) >= 0 ? "\"" + s.Replace("\"", "\"\"") + "\"" : s;

var sb = new StringBuilder();
sb.AppendLine("Folder,Name,Extension,SizeBytes,ModifiedUtc");
foreach (var f in files)
{
    sb.Append(Q(f.Folder)).Append(',')
      .Append(Q(f.Name)).Append(',')
      .Append(Q(f.Extension)).Append(',')
      .Append(f.Length.ToString(CultureInfo.InvariantCulture)).Append(',')
      .AppendLine(f.LastWriteTimeUtc.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));
}
File.WriteAllText(@"D:\Exports\files.csv", sb.ToString(), new UTF8Encoding(true)); // with BOM

Write a real .xlsx

To avoid separator and encoding questions entirely, create a workbook with ClosedXML (see Export GridView data to Excel for setup):

using ClosedXML.Excel;

using (var wb = new XLWorkbook())
{
    var ws = wb.Worksheets.Add("Files");
    ws.Cell(1, 1).InsertTable(files);   // header row from property names, formatted as a table
    ws.Columns().AdjustToContents();
    wb.SaveAs(@"D:\Exports\files.xlsx");
}

Sizes stay numeric and dates stay dates, so users can sort and sum them immediately.

From an ASP.NET page

Instead of saving to disk, send the bytes as a download with Content-Disposition: attachment, as in the GridView export article. Only list folders the application controls, and remember the application pool identity needs read access to them.

Large folders

For hundreds of thousands of files, building the whole CSV in a StringBuilder uses a lot of memory. Write directly to a StreamWriter created with new StreamWriter(path, false, new UTF8Encoding(true)) and write one line per file as you enumerate. The output is identical and memory use stays flat.

Official documentation