发布为答案,因为我没有代表添加评论,更不用说编辑现有答案了。我的要求是尽量减少内存分配、冗余变量,并让系统对目录进行一次枚举。
static IEnumerable<string> FindFiles(string path, string filter = "*", bool recursive = false)
{
IEnumerator<string> fEnum;
try
{
fEnum = Directory.EnumerateFiles(path, filter, recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).GetEnumerator();
}
catch (UnauthorizedAccessException) { yield break; }
while (true)
{
try { if (!fEnum.MoveNext()) break; }
catch (UnauthorizedAccessException) { continue; }
yield return fEnum.Current;
}
}
Dan Bechard 在评论中提到:
不幸的是,MoveNext() 在抛出异常时不会提前其位置。
这可能已在较新版本的 .Net 或 Windows 10 版本中得到修复?我在 Windows 10 上的 .NET 5.0 中没有这个问题。通过搜索我的整个系统驱动器进行了测试。
在 VB.NET 中:
Public Iterator Function FindFiles(path As String, Optional filter As String = "*", Optional recursive As Boolean = False) As IEnumerable(Of String)
Dim fEnum As IEnumerator(Of String)
Dim searchDepth = If(recursive, SearchOption.AllDirectories, SearchOption.TopDirectoryOnly)
Try
fEnum = Directory.EnumerateFiles(path, filter, searchDepth).GetEnumerator()
Catch uae As UnauthorizedAccessException
Return
End Try
Do While True
Try
If Not fEnum.MoveNext() Then Exit Do
Yield fEnum.Current
Catch uae As UnauthorizedAccessException
End Try
Loop
End Function