由于我没有足够的声望甚至无法编辑现有答案,所以我作为回答者进行回答。我的要求是尽可能减少内存分配、冗余变量,并使系统对目录进行单个枚举。
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
Dump()
方法,它只是遍历字符串枚举。问题在于Directory.EnumerateFiles
方法本身。我认为没有办法解决这个问题。你必须使用SearchOption.TopDirectoryOnly
并自己处理递归。 - Mormegil