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.