使用 IO.Directory.EnumerateDirectories 时如何忽略文档文件夹中的连接点

How to ignore Junction Points in Documents folder when using IO.Directory.EnumerateDirectories

    Dim dirs As List(Of String)
    dirs = New List(Of String)(IO.Directory.EnumerateDirectories(path, "*", SearchOption.AllDirectories))

以下代码大部分工作正常,但由于连接点的原因,在 c:\users\documents 文件夹中总是失败。

我得到以下异常和堆栈跟踪。

有没有办法排除连接点并使用 EnumerateDirectories,或者必须编写代码来手动获取目录名称和 ignore/handle 连接点?

异常:
{"Access to the path 'C:\Users\jkfredri\Documents\My Music' is denied."}

堆栈跟踪:
“在 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)” & vbCrLf & “在 System.IO.FileSystemEnumerableIterator1.AddSearchableDirsToStack(SearchData localSearchData)" & vbCrLf & " at System.IO.FileSystemEnumerableIterator1.MoveNext()” & vbCrLf & " at System.Collections.Generic.List1..ctor(IEnumerable1 collection)" & vbCrLf & " at BUDWindows.BUD.FileSystem.Directory.GetDirectoriesList(String path) in C:\Users\\Visual Studio\Projects\Desktop Applications\BUDWindows\Classes\FileSystemManager.vb:第 292 行

有一个 FileAttribute 表明它是否是 ReparsePoint 条目。为此,您需要一个 DirectoryInfo 对象。由于每个都需要测试,您可以使用 DirectoryInfo.EnumerateDirectories() 获取它们的列表,而不是根据您获得的名称一个一个地创建它们。

然后,如果您只想要名称,Select 排除了 ReparsePoint 之后的名称。扩展方法可以完成大部分工作:

Dim dInfo = New DirectoryInfo(dPath)
Dim DirNames = dInfo.EnumerateDirectories("*.*", SearchOption.TopDirectoryOnly).
                Where(Function(q) IsReparse(q) = False).
                Select(Function(q) q.FullName).
                ToList()

For Each s As String In DirNames.ToArray()
    DirNames.AddRange(Directory.
                        EnumerateDirectories(s, "*.*", SearchOption.AllDirectories))
Next

然后,辅助方法:

Private Function IsReparse(d As DirectoryInfo) As Boolean
    Return ((d.Attributes And FileAttributes.ReparsePoint) = FileAttributes.ReparsePoint)
End Function

这会获取 Reparse 属性为 false 的顶级文件夹名称,然后迭代这些名称以获取子文件夹名称。前提是 Reparse 文件夹将仅位于顶层。然后将其排除在外,它只是将子文件夹添加到列表中。

显然,即使首先测试 ReparsePoint 也不会阻止它在其中使用 SearchOption.AllDirectories.

查找子文件夹

您可以将 FileAttributes 测试放在 WHERE 方法中,但根据您的操作,您可能会发现您还想跳过带有 System 属性的测试。