While enumerating I would like to Skip/Ignore exception.
I try to add a try catch in the selector:
static IEnumerable<string> GetSafeAllFiles
(string path, string searchPattern, SearchOption searchOption = SearchOption.AllDirectories)
{
return Directory.EnumerateFiles(path, searchPattern, searchOption)
.Select(f =>
{
try
{
return f;
}
catch (Exception e)
{
return string.Empty;
}
});
}
I try using a solution from an accepted answer:
var test23 = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
.SkipExceptions().Take(100);
With no result, as it will stop after the first error. So I try to implement my own :
static IEnumerable<string> test12(string path, string searchPattern, SearchOption searchOption = SearchOption.AllDirectories)
{
if (string.IsNullOrEmpty(path))
{
throw new ArgumentNullException("path");
}
if (string.IsNullOrEmpty(searchPattern))
{
throw new ArgumentNullException("searchPattern");
}
Queue<string> stillToProcess = new Queue<string>(new[] { path });
foreach (var dir in Directory.EnumerateDirectories(path))
{
stillToProcess.Enqueue(dir);
}
while (stillToProcess.Count > 0)
{
string currentPath = stillToProcess.Dequeue();
IEnumerable<string> ret = Enumerable.Empty<string>();
try
{
ret = Directory.EnumerateFiles(currentPath, searchPattern);
}
catch (UnauthorizedAccessException e)
{ }
// yield! keyword
foreach (var i in ret) { yield return i; }
}
yield break;
}
But it skip directory if there is one error. When I want to skip only the error file.
In order to test, possible solution please do it on c:\$Recycle.Bin
, as it's the easiest source of UnauthorizedAccessException
.
This is what i came up with:
public static IEnumerable<FileInfo> EnumerateFilesIgnoreErrors(IEnumerable<FileInfo> files)
{
using (var e1 = files.GetEnumerator())
{
while (true)
{
FileInfo cur = null;
try
{
// MoveNext() can throw an Exception
if (! e1.MoveNext())
break;
cur = e1.Current;
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
if (cur != null)
{
yield return cur;
}
}
}
}
Use like this:
var myFiles = new DirectoryInfo(@"C:\")
.EnumerateFiles("*", SearchOption.AllDirectories);
foreach (FileInfo fi in EnumerateFilesIgnoreErrors(myFiles))
{
Debug.WriteLine(fi.Name);
}
You can also use it like this:
var myList = EnumerateFilesIgnoreErrors(myFiles).ToList();
Works on "c:\$Recycle.Bin" etc
Ignores UnauthorizedAccessException
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With