Nota: Si alquien quiere comparar este código con algún otro algoritmo (que de seguro los hay mejores) para hacer algún tipo de profilling de I/O o del rendimiento de memoria entonces no se vayan a asustar por el consumo de memoria al recojer +100k de archivos, es el GarbageCollector de .Net haciendo de las suyas... lo pueden invokar manualmente (GC.Collect) y desaparecerá todo ese consumo ficticio de RAM.
Espero que a alguien le sirva el code :
Código
' *********************************************************************** ' Author : Elektro ' Modified : 14-February-2015 ' *********************************************************************** #Region " Usage Examples " ' he eliminado esto por el límite de caracteres del foro #End Region #Region " Option Statements " Option Explicit On Option Strict On Option Infer Off #End Region #Region " Imports " Imports System.IO Imports System.Collections.Concurrent Imports System.Threading.Tasks #End Region #Region " File Dir Searcher " ''' <summary> ''' Searchs for files and directories. ''' </summary> Public NotInheritable Class FileDirSearcher #Region " Public Methods " ''' <summary> ''' Gets the files those matches the criteria inside the specified directory and/or sub-directories. ''' </summary> ''' <param name="dirPath">The root directory path to search for files.</param> ''' <param name="searchOption">The searching mode.</param> ''' <param name="fileNamePatterns">The file name pattern(s) to match.</param> ''' <param name="fileExtPatterns">The file extension pattern(s) to match.</param> ''' <param name="ignoreCase">If <c>True</c>, ignores the comparing case of <paramref name="fileNamePatterns"/> and <paramref name="fileExtPatterns"/> patterns.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to file or directory.</param> ''' <returns>An <see cref="IEnumerable(Of FileInfo)"/> instance containing the files information.</returns> ''' <exception cref="System.ArgumentException">dirPath or searchOption</exception> Public Shared Function GetFiles(ByVal dirPath As String, ByVal searchOption As SearchOption, Optional ByVal fileNamePatterns As IEnumerable(Of String) = Nothing, Optional ByVal fileExtPatterns As IEnumerable(Of String) = Nothing, Optional ByVal ignoreCase As Boolean = True, Optional ByVal throwOnError As Boolean = False) As IEnumerable(Of FileInfo) ' Analyze and resolve path problems. (eg. 'C:' -> 'C:\') AnalyzePath(dirPath) ' Analyze the passed arguments. AnalyzeArgs(dirPath, searchOption) ' Get and return the files. Dim queue As New ConcurrentQueue(Of FileInfo) CollectFiles(queue, dirPath, searchOption, fileNamePatterns, fileExtPatterns, ignoreCase, throwOnError) Return queue.AsEnumerable End Function ''' <summary> ''' Gets the filepaths those matches the criteria inside the specified directory and/or sub-directories. ''' </summary> ''' <param name="dirPath">The root directory path to search for files.</param> ''' <param name="searchOption">The searching mode.</param> ''' <param name="fileNamePatterns">The file name pattern(s) to match.</param> ''' <param name="fileExtPatterns">The file extension pattern(s) to match.</param> ''' <param name="ignoreCase">If <c>True</c>, ignores the comparing case of <paramref name="fileNamePatterns"/> and <paramref name="fileExtPatterns"/> patterns.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to file or directory.</param> ''' <returns>An <see cref="IEnumerable(Of String)"/> instance containing the filepaths.</returns> ''' <exception cref="System.ArgumentException">dirPath or searchOption</exception> Public Shared Function GetFilePaths(ByVal dirPath As String, ByVal searchOption As SearchOption, Optional ByVal fileNamePatterns As IEnumerable(Of String) = Nothing, Optional ByVal fileExtPatterns As IEnumerable(Of String) = Nothing, Optional ByVal ignoreCase As Boolean = True, Optional ByVal throwOnError As Boolean = False) As IEnumerable(Of String) ' Analyze and resolve path problems. (eg. 'C:' -> 'C:\') AnalyzePath(dirPath) ' Analyze the passed arguments. AnalyzeArgs(dirPath, searchOption) ' Get and return the filepaths. Dim queue As New ConcurrentQueue(Of String) CollectFilePaths(queue, dirPath, searchOption, fileNamePatterns, fileExtPatterns, ignoreCase, throwOnError) Return queue.AsEnumerable End Function ''' <summary> ''' Gets the directories those matches the criteria inside the specified directory and/or sub-directories. ''' </summary> ''' <param name="dirPath">The root directory path to search for directories.</param> ''' <param name="searchOption">The searching mode.</param> ''' <param name="dirPathPatterns">The directory path pattern(s) to match.</param> ''' <param name="dirNamePatterns">The directory name pattern(s) to match.</param> ''' <param name="ignoreCase">If <c>True</c>, ignores the comparing case of <paramref name="dirPathPatterns"/> and <paramref name="dirNamePatterns"/> patterns.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to directory.</param> ''' <returns>An <see cref="IEnumerable(Of DirectoryInfo)"/> instance containing the dirrectories information.</returns> ''' <exception cref="System.ArgumentException">dirPath or searchOption</exception> Public Shared Function GetDirs(ByVal dirPath As String, ByVal searchOption As SearchOption, Optional ByVal dirPathPatterns As IEnumerable(Of String) = Nothing, Optional ByVal dirNamePatterns As IEnumerable(Of String) = Nothing, Optional ByVal ignoreCase As Boolean = True, Optional ByVal throwOnError As Boolean = False) As IEnumerable(Of DirectoryInfo) ' Analyze and resolve path problems. (eg. 'C:' -> 'C:\') AnalyzePath(dirPath) ' Analyze the passed arguments. AnalyzeArgs(dirPath, searchOption) ' Get and return the directories. Dim queue As New ConcurrentQueue(Of DirectoryInfo) CollectDirs(queue, dirPath, searchOption, dirPathPatterns, dirNamePatterns, ignoreCase, throwOnError) Return queue.AsEnumerable End Function ''' <summary> ''' Gets the filepaths those matches the criteria inside the specified directory and/or sub-directories. ''' </summary> ''' <param name="dirPath">The root directory path to search for directories.</param> ''' <param name="searchOption">The searching mode.</param> ''' <param name="dirPathPatterns">The directory path pattern(s) to match.</param> ''' <param name="dirNamePatterns">The directory name pattern(s) to match.</param> ''' <param name="ignoreCase">If <c>True</c>, ignores the comparing case of <paramref name="dirPathPatterns"/> and <paramref name="dirNamePatterns"/> patterns.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to directory.</param> ''' <returns>An <see cref="IEnumerable(Of String)"/> instance containing the directory paths.</returns> ''' <exception cref="System.ArgumentException">dirPath or searchOption</exception> Public Shared Function GetDirPaths(ByVal dirPath As String, ByVal searchOption As SearchOption, Optional ByVal dirPathPatterns As IEnumerable(Of String) = Nothing, Optional ByVal dirNamePatterns As IEnumerable(Of String) = Nothing, Optional ByVal ignoreCase As Boolean = True, Optional ByVal throwOnError As Boolean = False) As IEnumerable(Of String) ' Analyze and resolve path problems. (eg. 'C:' -> 'C:\') AnalyzePath(dirPath) ' Analyze the passed arguments. AnalyzeArgs(dirPath, searchOption) ' Get and return the directory paths. Dim queue As New ConcurrentQueue(Of String) CollectDirPaths(queue, dirPath, searchOption, dirPathPatterns, dirNamePatterns, ignoreCase, throwOnError) Return queue.AsEnumerable End Function #End Region #Region " Private Methods " ''' <summary> ''' Analyzes a directory path and perform specific changes on it. ''' </summary> ''' <param name="dirPath">The directory path.</param> ''' <exception cref="System.ArgumentNullException">dirPath;Value is null, empty, or white-spaced.</exception> Private Shared Sub AnalyzePath(ByRef dirPath As String) If String.IsNullOrEmpty(dirPath) OrElse String.IsNullOrWhiteSpace(dirPath) Then Throw New ArgumentNullException("dirPath", "Value is null, empty, or white-spaced.") Else ' Trim unwanted characters. dirPath = dirPath.TrimStart({" "c}).TrimEnd({" "c}) If Path.IsPathRooted(dirPath) Then ' The root paths contained on the returned FileInfo objects will start with the same string-case as this root path. ' So just for a little visual improvement, I'll treat this root path as a Drive-Letter and I convert it to UpperCase. dirPath = Char.ToUpper(dirPath.First) & dirPath.Substring(1) End If If Not dirPath.EndsWith("\"c) Then ' Possibly its a drive letter without backslash ('C:') or else just a normal path without backslash ('C\Dir'). ' In any case, fix the ending backslash. dirPath = dirPath.Insert(dirPath.Length, "\"c) End If End If End Sub ''' <summary> ''' Analyzes the specified directory values. ''' </summary> ''' <param name="dirPath">The root directory path to search for files.</param> ''' <param name="searchOption">The searching mode.</param> ''' <exception cref="System.ArgumentException">dirPath or searchOption</exception> Private Shared Sub AnalyzeArgs(ByVal dirPath As String, ByVal searchOption As SearchOption) If Not Directory.Exists(dirPath) Then Throw New ArgumentException(String.Format("Directory doesn't exists: '{0}'", dirPath), "dirPath") ElseIf (searchOption <> searchOption.TopDirectoryOnly) AndAlso (searchOption <> searchOption.AllDirectories) Then Throw New ArgumentException(String.Format("Value of '{0}' is not valid enumeration value.", CStr(searchOption)), "searchOption") End If End Sub ''' <summary> ''' Tries to instance the byreferred <see cref="DirectoryInfo"/> object using the given directory path. ''' </summary> ''' <param name="dirPath">The directory path used to instance the byreffered <see cref="DirectoryInfo"/> object.</param> ''' <param name="dirInfo">The byreffered <see cref="DirectoryInfo"/> object to instance it using the given directory path.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to directory.</param> Private Shared Sub SetupDirInfoObject(ByVal dirPath As String, ByRef dirInfo As DirectoryInfo, ByVal throwOnError As Boolean) Try dirInfo = New DirectoryInfo(dirPath) Catch ex As Exception Select Case ex.GetType ' Handle or suppress exceptions by its type, ' I've wrote different types just to feel free to expand this feature in the future. Case GetType(ArgumentNullException), GetType(ArgumentException), GetType(Security.SecurityException), GetType(PathTooLongException), ex.GetType If throwOnError Then Throw End If End Select End Try End Sub ''' <summary> ''' Tries to instance the byreferred <paramref name="col"/> object using the given directory path. ''' </summary> ''' <typeparam name="A">The type of the <paramref name="col"/> object used to cast and fill the byreffered collection.</typeparam> ''' <param name="objectAction">The method to invoke, only for <see cref="FileInfo"/> or <see cref="DirectoryInfo"/> objects, this parameter can be <c>Nothing</c>.</param> ''' <param name="sharedAction">The method to invoke, only for filepaths or directorypaths, this parameter can be <c>Nothing</c>.</param> ''' <param name="dirPath">The directory path used to instance the byreffered <paramref name="col"/> object.</param> ''' <param name="searchPattern">The search pattern to list files or directories.</param> ''' <param name="col">The byreffered <see cref="IEnumerable(Of A)"/> object to instance it using the given directory path.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to file or directory.</param> Private Shared Sub SetupFileDirCollection(Of A)(ByVal objectAction As Func(Of String, SearchOption, IEnumerable(Of A)), ByVal sharedAction As Func(Of String, String, SearchOption, IEnumerable(Of A)), ByVal dirPath As String, ByVal searchPattern As String, ByRef col As IEnumerable(Of A), ByVal throwOnError As Boolean) Try If objectAction IsNot Nothing Then col = objectAction.Invoke(searchPattern, SearchOption.TopDirectoryOnly) ElseIf sharedAction IsNot Nothing Then col = sharedAction.Invoke(dirPath, searchPattern, SearchOption.TopDirectoryOnly) Else Throw New ArgumentException("Any Action has been defined.") End If Catch ex As Exception Select Case ex.GetType ' Handle or suppress exceptions by its type, ' I've wrote different types just to feel free to expand this feature in the future. Case GetType(UnauthorizedAccessException), GetType(DirectoryNotFoundException), ex.GetType If throwOnError Then Throw End If End Select End Try End Sub ''' <summary> ''' Determines whether at least one of the specified patterns matches the given value. ''' </summary> ''' <param name="value">The value, which can be a filename, file extension, direcrory path, or directory name.</param> ''' <param name="patterns">The patterns to match the given value.</param> ''' <param name="ignoreCase">if set to <c>true</c>, compares ignoring string-case rules.</param> ''' <returns><c>true</c> at least one of the specified patterns matches the given value; <c>false</c> otherwise.</returns> Private Shared Function IsMatchPattern(ByVal value As String, ByVal patterns As IEnumerable(Of String), ByVal ignoreCase As Boolean) As Boolean ' Iterate the filename pattern(s) to match each name pattern on the current name. For Each pattern As String In patterns ' Supress consecuent conditionals if pattern its an asterisk. If pattern.Equals("*", StringComparison.OrdinalIgnoreCase) Then Return True ElseIf ignoreCase Then ' Compare name ignoring string-case rules. If value.ToLower Like pattern.ToLower Then Return True End If Else ' Compare filename unignoring string-case rules. If value Like pattern Then Return True End If End If ' ignoreCase Next pattern Return False End Function ''' <summary> ''' Runs the next collector tasks synchronouslly. ''' </summary> ''' <typeparam name="T"></typeparam> ''' <param name="action">The collector method to invoke.</param> ''' <param name="queue">The <see cref="ConcurrentQueue(Of FileInfo)"/> instance.</param> ''' <param name="dirPath">The directory path.</param> ''' <param name="firstPatterns">The first comparison patterns.</param> ''' <param name="secondPatterns">The second comparison patterns.</param> ''' <param name="ignoreCase">if set to <c>true</c>, compares ignoring string-case rules.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to file or directory.</param> Private Shared Sub RunNextTasks(Of T)(ByVal action As Action(Of ConcurrentQueue(Of T), String, SearchOption, IEnumerable(Of String), IEnumerable(Of String), Boolean, Boolean), ByVal queue As ConcurrentQueue(Of T), ByVal dirPath As String, ByVal firstPatterns As IEnumerable(Of String), ByVal secondPatterns As IEnumerable(Of String), ByVal ignoreCase As Boolean, ByVal throwOnError As Boolean) Try Task.WaitAll(New DirectoryInfo(dirPath). GetDirectories. Select(Function(dir As DirectoryInfo) Return Task.Factory.StartNew(Sub() action.Invoke(queue, dir.FullName, SearchOption.AllDirectories, firstPatterns, secondPatterns, ignoreCase, throwOnError) End Sub) End Function).ToArray) Catch ex As Exception Select Case ex.GetType ' Handle or suppress exceptions by its type, ' I've wrote different types just to feel free to expand this feature in the future. Case GetType(UnauthorizedAccessException), GetType(DirectoryNotFoundException), ex.GetType If throwOnError Then Throw End If End Select End Try End Sub ''' <summary> ''' Collects the files those matches the criteria inside the specified directory and/or sub-directories. ''' </summary> ''' <param name="queue">The <see cref="ConcurrentQueue(Of FileInfo)"/> instance to enqueue new files.</param> ''' <param name="dirPath">The root directory path to search for files.</param> ''' <param name="searchOption">The searching mode.</param> ''' <param name="fileNamePatterns">The file name pattern(s) to match.</param> ''' <param name="fileExtPatterns">The file extension pattern(s) to match.</param> ''' <param name="ignoreCase">If <c>True</c>, ignores the comparing case of <paramref name="fileNamePatterns"/> and <paramref name="fileExtPatterns"/> patterns.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to file or directory.</param> Private Shared Sub CollectFiles(ByVal queue As ConcurrentQueue(Of FileInfo), ByVal dirPath As String, ByVal searchOption As SearchOption, ByVal fileNamePatterns As IEnumerable(Of String), ByVal fileExtPatterns As IEnumerable(Of String), ByVal ignoreCase As Boolean, ByVal throwOnError As Boolean) ' Initialize a FileInfo collection. Dim fileInfoCol As IEnumerable(Of FileInfo) = Nothing ' Initialize a DirectoryInfo. Dim dirInfo As DirectoryInfo = Nothing SetupDirInfoObject(dirPath, dirInfo, throwOnError) If fileExtPatterns IsNot Nothing Then ' Decrease time execution by searching for files that has extension. SetupFileDirCollection(Of FileInfo)(AddressOf dirInfo.GetFiles, Nothing, dirInfo.FullName, "*.*", fileInfoCol, throwOnError) Else ' Search for all files. SetupFileDirCollection(Of FileInfo)(AddressOf dirInfo.GetFiles, Nothing, dirInfo.FullName, "*", fileInfoCol, throwOnError) End If ' If the fileInfoCol collection is not empty then... If fileInfoCol IsNot Nothing Then ' Iterate the files. For Each fInfo As FileInfo In fileInfoCol ' Flag to determine whether a filename pattern is matched. Activated by default. Dim flagNamePattern As Boolean = True ' Flag to determine whether a file extension pattern is matched. Activated by default. Dim flagExtPattern As Boolean = True ' If filename patterns collection is not empty then... If fileNamePatterns IsNot Nothing Then flagNamePattern = IsMatchPattern(fInfo.Name, fileNamePatterns, ignoreCase) End If ' If file extension patterns collection is not empty then... If fileExtPatterns IsNot Nothing Then flagExtPattern = IsMatchPattern(fInfo.Extension, fileExtPatterns, ignoreCase) End If ' If fileName and also fileExtension patterns are matched then... If flagNamePattern AndAlso flagExtPattern Then queue.Enqueue(fInfo) ' Enqueue this FileInfo object. End If Next fInfo End If ' fileInfoCol IsNot Nothing ' If searchOption is recursive then... If searchOption = searchOption.AllDirectories Then RunNextTasks(Of FileInfo)(AddressOf CollectFiles, queue, dirInfo.FullName, fileNamePatterns, fileExtPatterns, ignoreCase, throwOnError) End If End Sub ''' <summary> ''' Collects the filepaths those matches the criteria inside the specified directory and/or sub-directories. ''' </summary> ''' <param name="queue">The <see cref="ConcurrentQueue(Of String)"/> instance to enqueue new filepaths.</param> ''' <param name="dirPath">The root directory path to search for files.</param> ''' <param name="searchOption">The searching mode.</param> ''' <param name="fileNamePatterns">The file name pattern(s) to match.</param> ''' <param name="fileExtPatterns">The file extension pattern(s) to match.</param> ''' <param name="ignoreCase">If <c>True</c>, ignores the comparing case of <paramref name="fileNamePatterns"/> and <paramref name="fileExtPatterns"/> patterns.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to file or directory.</param> Private Shared Sub CollectFilePaths(ByVal queue As ConcurrentQueue(Of String), ByVal dirPath As String, ByVal searchOption As SearchOption, ByVal fileNamePatterns As IEnumerable(Of String), ByVal fileExtPatterns As IEnumerable(Of String), ByVal ignoreCase As Boolean, ByVal throwOnError As Boolean) ' Initialize a filepath collection. Dim filePathCol As IEnumerable(Of String) = Nothing If fileExtPatterns IsNot Nothing Then ' Decrease time execution by searching for files that has extension. SetupFileDirCollection(Of String)(Nothing, AddressOf Directory.GetFiles, dirPath, "*.*", filePathCol, throwOnError) Else ' Search for all files. SetupFileDirCollection(Of String)(Nothing, AddressOf Directory.GetFiles, dirPath, "*", filePathCol, throwOnError) End If ' If the filepath collection is not empty then... If filePathCol IsNot Nothing Then ' Iterate the filepaths. For Each filePath As String In filePathCol ' Flag to determine whether a filename pattern is matched. Activated by default. Dim flagNamePattern As Boolean = True ' Flag to determine whether a file extension pattern is matched. Activated by default. Dim flagExtPattern As Boolean = True ' If filename patterns collection is not empty then... If fileNamePatterns IsNot Nothing Then flagNamePattern = IsMatchPattern(Path.GetFileNameWithoutExtension(filePath), fileNamePatterns, ignoreCase) End If ' If file extension patterns collection is not empty then... If fileExtPatterns IsNot Nothing Then flagExtPattern = IsMatchPattern(Path.GetExtension(filePath), fileExtPatterns, ignoreCase) End If ' If fileName and also fileExtension patterns are matched then... If flagNamePattern AndAlso flagExtPattern Then queue.Enqueue(filePath) ' Enqueue this filepath. End If Next filePath End If ' filePathCol IsNot Nothing ' If searchOption is recursive then... If searchOption = searchOption.AllDirectories Then RunNextTasks(Of String)(AddressOf CollectFilePaths, queue, dirPath, fileNamePatterns, fileExtPatterns, ignoreCase, throwOnError) End If End Sub ''' <summary> ''' Collects the directories those matches the criteria inside the specified directory and/or sub-directories. ''' </summary> ''' <param name="queue">The <see cref="ConcurrentQueue(Of DirectoryInfo)"/> instance to enqueue new directories.</param> ''' <param name="dirPath">The root directory path to search for directories.</param> ''' <param name="searchOption">The searching mode.</param> ''' <param name="dirPathPatterns">The directory path pattern(s) to match.</param> ''' <param name="dirNamePatterns">The directory name pattern(s) to match.</param> ''' <param name="ignoreCase">If <c>True</c>, ignores the comparing case of <paramref name="dirPathPatterns"/> and <paramref name="dirNamePatterns"/> patterns.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to directory.</param> Private Shared Sub CollectDirs(ByVal queue As ConcurrentQueue(Of DirectoryInfo), ByVal dirPath As String, ByVal searchOption As SearchOption, ByVal dirPathPatterns As IEnumerable(Of String), ByVal dirNamePatterns As IEnumerable(Of String), ByVal ignoreCase As Boolean, ByVal throwOnError As Boolean) ' Initialize a DirectoryInfo collection. Dim dirInfoCol As IEnumerable(Of DirectoryInfo) = Nothing ' Initialize a DirectoryInfo. Dim dirInfo As DirectoryInfo = Nothing SetupDirInfoObject(dirPath, dirInfo, throwOnError) ' Get the top directories of the current directory. SetupFileDirCollection(Of DirectoryInfo)(AddressOf dirInfo.GetDirectories, Nothing, dirInfo.FullName, "*", dirInfoCol, throwOnError) ' If the fileInfoCol collection is not empty then... If dirInfoCol IsNot Nothing Then ' Iterate the files. For Each dir As DirectoryInfo In dirInfoCol ' Flag to determine whether a directory path pattern is matched. Activated by default. Dim flagPathPattern As Boolean = True ' Flag to determine whether a directory name pattern is matched. Activated by default. Dim flagNamePattern As Boolean = True ' If directory path patterns collection is not empty then... If dirPathPatterns IsNot Nothing Then flagPathPattern = IsMatchPattern(dir.FullName, dirPathPatterns, ignoreCase) End If ' If directory name patterns collection is not empty then... If dirNamePatterns IsNot Nothing Then flagNamePattern = IsMatchPattern(dir.Name, dirNamePatterns, ignoreCase) End If ' If directory path and also directory name patterns are matched then... If flagPathPattern AndAlso flagNamePattern Then queue.Enqueue(dir) ' Enqueue this DirectoryInfo object. End If Next dir End If ' dirInfoCol IsNot Nothing ' If searchOption is recursive then... If searchOption = searchOption.AllDirectories Then RunNextTasks(Of DirectoryInfo)(AddressOf CollectDirs, queue, dirPath, dirPathPatterns, dirNamePatterns, ignoreCase, throwOnError) End If End Sub ''' <summary> ''' Collects the directory paths those matches the criteria inside the specified directory and/or sub-directories. ''' </summary> ''' <param name="queue">The <see cref="ConcurrentQueue(Of String)"/> instance to enqueue new directory paths.</param> ''' <param name="dirPath">The root directory path to search for directories.</param> ''' <param name="searchOption">The searching mode.</param> ''' <param name="dirPathPatterns">The directory path pattern(s) to match.</param> ''' <param name="dirNamePatterns">The directory name pattern(s) to match.</param> ''' <param name="ignoreCase">If <c>True</c>, ignores the comparing case of <paramref name="dirPathPatterns"/> and <paramref name="dirNamePatterns"/> patterns.</param> ''' <param name="throwOnError">If set to <c>true</c>, exceptions will be thrown, like access denied to directory.</param> Private Shared Sub CollectDirPaths(ByVal queue As ConcurrentQueue(Of String), ByVal dirPath As String, ByVal searchOption As SearchOption, ByVal dirPathPatterns As IEnumerable(Of String), ByVal dirNamePatterns As IEnumerable(Of String), ByVal ignoreCase As Boolean, ByVal throwOnError As Boolean) ' Initialize a directory paths collection. Dim dirPathCol As IEnumerable(Of String) = Nothing ' Get the top directory paths of the current directory. SetupFileDirCollection(Of String)(Nothing, AddressOf Directory.GetDirectories, dirPath, "*", dirPathCol, throwOnError) ' If the fileInfoCol collection is not empty then... If dirPathCol IsNot Nothing Then ' Iterate the files. For Each dir As String In dirPathCol ' Flag to determine whether a directory path pattern is matched. Activated by default. Dim flagPathPattern As Boolean = True ' Flag to determine whether a directory name pattern is matched. Activated by default. Dim flagNamePattern As Boolean = True ' If directory path patterns collection is not empty then... If dirPathPatterns IsNot Nothing Then flagPathPattern = IsMatchPattern(dir, dirPathPatterns, ignoreCase) End If ' If directory name patterns collection is not empty then... If dirNamePatterns IsNot Nothing Then flagNamePattern = IsMatchPattern(Path.GetFileName(dir), dirNamePatterns, ignoreCase) End If ' If directory path and also directory name patterns are matched then... If flagPathPattern AndAlso flagNamePattern Then queue.Enqueue(dir) ' Enqueue this directory path. End If Next dir End If ' dirPathCol IsNot Nothing ' If searchOption is recursive then... If searchOption = searchOption.AllDirectories Then RunNextTasks(Of String)(AddressOf CollectDirPaths, queue, dirPath, dirPathPatterns, dirNamePatterns, ignoreCase, throwOnError) End If End Sub #End Region End Class #End Region