c# – DirectoryInfo.EnumerateFiles => Exception

Question:

You need to get all the files using the specified mask. The EnumerateFiles method throws an exception if a file has system permissions. How to get around this?

var sourceDir = new DirectoryInfo(path);
foreach (var f in sourceDir.EnumerateFiles("*.txt", SearchOption.AllDirectories))
{
     var lvItem = new ListViewItem(Path.GetFileName(f.FullName), 0);
     lvItem.SubItems.Add(Path.GetDirectoryName(f.FullName));
     var fileInfo = new FileInfo(f.FullName);
     lvItem.SubItems.Add(fileInfo.Length + " байт");
     lvItem.SubItems.Add(Directory.GetLastWriteTime(f.FullName).ToShortDateString());
     uiContext.Send(d => listView1.Items.Add(lvItem), null);
}

Answer:

Apparently, there is nothing better than manual recursion with catching exceptions.

You can try this:

static IEnumerable<FileInfo> EnumerateFilesDeepIgnoringAccessException(
    DirectoryInfo root, string mask)
{
    var localResult = new List<FileInfo>();
    try
    {
        localResult = root.EnumerateFiles(mask).ToList();
    }
    catch (UnauthorizedAccessException)
    {
        // ignore it
        yield break;
    }

    foreach (var fi in localResult)
        yield return fi;

    foreach (var di in root.EnumerateDirectories())
    {
        foreach (var fi in EnumerateFilesDeepIgnoringAccessException(di, mask))
            yield return fi;
    }
}

The code is based on the official example , modified for lazy traversal.


You can also get rid of recursion in the standard way – add an explicit queue of directories for traversal. However, I do not think that this will give a significant speed benefit compared to bypassing the file system.


Specifically for your code, I would not go about traversing the file system on the same thread as the UI is running – otherwise freezes cannot be avoided. You should consider crawling in a separate thread.

Scroll to Top