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

时间:2017-01-04 21:06:31

标签: .net vb.net windows directory filesystems

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

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

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

有没有办法排除交接点并使用EnumerateDirectories,还是必须编写代码来手动获取目录名称并忽略/处理交接点?

例外:
{"访问路径' C:\ Users \ jkfredri \ Documents \ My Music'被拒绝。"}

堆栈追踪:
"在System.IO .__ Error.WinIOError(Int32 errorCode,String maybeFullPath)" &安培; vbCrLf& "在System.IO.FileSystemEnumerableIterator 1.AddSearchableDirsToStack(SearchData localSearchData)" & vbCrLf & " at System.IO.FileSystemEnumerableIterator 1.MoveNext()" &安培; vbCrLf& "在System.Collections.Generic.List 1..ctor(IEnumerable 1个集合)" &安培; vbCrLf& "位于C:\ Users \\ Visual Studio \ Projects \ Desktop Applications \ BUDWindows \ Classes \ FileSystemManager.vb中的BUDWindows.BUD.FileSystem.Directory.GetDirectoriesList(字符串路径):第292行"

1 个答案:

答案 0 :(得分:1)

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属性的测试。