Advertisement
Guest User

Untitled

a guest
Apr 14th, 2018
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 45.91 KB | None | 0 0
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 14-November-2015
  4. ' ***********************************************************************
  5.  
  6. #Region " Option Statements "
  7.  
  8. Option Strict On
  9. Option Explicit On
  10. Option Infer Off
  11.  
  12. #End Region
  13.  
  14. #Region " Imports "
  15.  
  16. Imports System.Collections.Concurrent
  17. Imports System.IO
  18. Imports System.Linq
  19. Imports System.Security
  20. Imports System.Threading.Tasks
  21.  
  22. ' Imports ElektroKit.Core.Types
  23.  
  24. #End Region
  25.  
  26. #Region " File/Directory Searcher "
  27.  
  28. 'Namespace IO.Tools
  29.  
  30.     Friend NotInheritable Class FileDirSearcher ': Inherits AestheticObject
  31.  
  32. #Region " Constructors "
  33.  
  34.         ''' ----------------------------------------------------------------------------------------------------
  35.         ''' <summary>
  36.         ''' Prevents a default instance of the <see cref="FileDirSearcher"/> class from being created.
  37.         ''' </summary>
  38.         ''' ----------------------------------------------------------------------------------------------------
  39.         <DebuggerNonUserCode>
  40.         Private Sub New()
  41.         End Sub
  42.  
  43. #End Region
  44.  
  45. #Region " Public Methods "
  46.  
  47.         ''' ----------------------------------------------------------------------------------------------------
  48.         ''' <summary>
  49.         ''' Gets the files those matches the criteria inside the specified directory and/or sub-directories.
  50.         ''' </summary>
  51.         ''' ----------------------------------------------------------------------------------------------------
  52.         ''' <param name="dirPath">
  53.         ''' The root directory path to search for files.
  54.         ''' </param>
  55.         '''
  56.         ''' <param name="searchOption">
  57.         ''' The searching mode.
  58.         ''' </param>
  59.         '''
  60.         ''' <param name="fileNamePatterns">
  61.         ''' The file name pattern(s) to match.
  62.         ''' </param>
  63.         '''
  64.         ''' <param name="fileExtPatterns">
  65.         ''' The file extension pattern(s) to match.
  66.         ''' </param>
  67.         '''
  68.         ''' <param name="ignoreCase">
  69.         ''' If <see langword="True"/>, ignores the comparing case of <paramref name="fileNamePatterns"/> and <paramref name="fileExtPatterns"/> patterns.
  70.         ''' </param>
  71.         '''
  72.         ''' <param name="throwOnError">
  73.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to file or directory.
  74.         ''' </param>
  75.         ''' ----------------------------------------------------------------------------------------------------
  76.         ''' <returns>
  77.         ''' An <see cref="IEnumerable(Of FileInfo)"/> instance containing the files information.
  78.         ''' </returns>
  79.         ''' ----------------------------------------------------------------------------------------------------
  80.         ''' <exception cref="Global.System.ArgumentException">dirPath or searchOption
  81.         ''' </exception>
  82.         ''' ----------------------------------------------------------------------------------------------------
  83.         <DebuggerStepThrough>
  84.         Friend Shared Function GetFiles(ByVal dirPath As String,
  85.                                          ByVal searchOption As SearchOption,
  86.                                          Optional ByVal fileNamePatterns As IEnumerable(Of String) = Nothing,
  87.                                          Optional ByVal fileExtPatterns As IEnumerable(Of String) = Nothing,
  88.                                          Optional ByVal ignoreCase As Boolean = True,
  89.                                          Optional ByVal throwOnError As Boolean = False) As IEnumerable(Of FileInfo)
  90.  
  91.             ' Analyze and resolve path problems. (eg. 'C:' -> 'C:\')
  92.             FileDirSearcher.AnalyzePath(dirPath)
  93.  
  94.             ' Analyze the passed arguments.
  95.             FileDirSearcher.AnalyzeArgs(dirPath, searchOption)
  96.  
  97.             ' Get and return the files.
  98.             Dim queue As New ConcurrentQueue(Of FileInfo)
  99.             FileDirSearcher.CollectFiles(queue, dirPath, searchOption, fileNamePatterns, fileExtPatterns, ignoreCase, throwOnError)
  100.             Return queue.AsEnumerable
  101.  
  102.         End Function
  103.  
  104.         ''' ----------------------------------------------------------------------------------------------------
  105.         ''' <summary>
  106.         ''' Gets the filepaths those matches the criteria inside the specified directory and/or sub-directories.
  107.         ''' </summary>
  108.         ''' ----------------------------------------------------------------------------------------------------
  109.         ''' <param name="dirPath">
  110.         ''' The root directory path to search for files.
  111.         ''' </param>
  112.         '''
  113.         ''' <param name="searchOption">
  114.         ''' The searching mode.
  115.         ''' </param>
  116.         '''
  117.         ''' <param name="fileNamePatterns">
  118.         ''' The file name pattern(s) to match.
  119.         ''' </param>
  120.         '''
  121.         ''' <param name="fileExtPatterns">
  122.         ''' The file extension pattern(s) to match.
  123.         ''' </param>
  124.         '''
  125.         ''' <param name="ignoreCase">
  126.         ''' If <see langword="True"/>, ignores the comparing case of <paramref name="fileNamePatterns"/> and <paramref name="fileExtPatterns"/> patterns.
  127.         ''' </param>
  128.         '''
  129.         ''' <param name="throwOnError">
  130.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to file or directory.
  131.         ''' </param>
  132.         ''' ----------------------------------------------------------------------------------------------------
  133.         ''' <returns>
  134.         ''' An <see cref="IEnumerable(Of String)"/> instance containing the filepaths.
  135.         ''' </returns>
  136.         ''' ----------------------------------------------------------------------------------------------------
  137.         ''' <exception cref="Global.System.ArgumentException">dirPath or searchOption
  138.         ''' </exception>
  139.         ''' ----------------------------------------------------------------------------------------------------
  140.         <DebuggerStepThrough>
  141.         Friend Shared Function GetFilePaths(ByVal dirPath As String,
  142.                                              ByVal searchOption As SearchOption,
  143.                                              Optional ByVal fileNamePatterns As IEnumerable(Of String) = Nothing,
  144.                                              Optional ByVal fileExtPatterns As IEnumerable(Of String) = Nothing,
  145.                                              Optional ByVal ignoreCase As Boolean = True,
  146.                                              Optional ByVal throwOnError As Boolean = False) As IEnumerable(Of String)
  147.  
  148.             ' Analyze and resolve path problems. (eg. 'C:' -> 'C:\')
  149.             FileDirSearcher.AnalyzePath(dirPath)
  150.  
  151.             ' Analyze the passed arguments.
  152.             FileDirSearcher.AnalyzeArgs(dirPath, searchOption)
  153.  
  154.             ' Get and return the filepaths.
  155.             Dim queue As New ConcurrentQueue(Of String)
  156.             FileDirSearcher.CollectFilePaths(queue, dirPath, searchOption, fileNamePatterns, fileExtPatterns, ignoreCase, throwOnError)
  157.             Return queue.AsEnumerable
  158.  
  159.         End Function
  160.  
  161.         ''' ----------------------------------------------------------------------------------------------------
  162.         ''' <summary>
  163.         ''' Gets the directories those matches the criteria inside the specified directory and/or sub-directories.
  164.         ''' </summary>
  165.         ''' ----------------------------------------------------------------------------------------------------
  166.         ''' <param name="dirPath">
  167.         ''' The root directory path to search for directories.
  168.         ''' </param>
  169.         '''
  170.         ''' <param name="searchOption">
  171.         ''' The searching mode.
  172.         ''' </param>
  173.         '''
  174.         ''' <param name="dirPathPatterns">
  175.         ''' The directory path pattern(s) to match.
  176.         ''' </param>
  177.         '''
  178.         ''' <param name="dirNamePatterns">
  179.         ''' The directory name pattern(s) to match.
  180.         ''' </param>
  181.         '''
  182.         ''' <param name="ignoreCase">
  183.         ''' If <see langword="True"/>, ignores the comparing case of <paramref name="dirPathPatterns"/> and <paramref name="dirNamePatterns"/> patterns.
  184.         ''' </param>
  185.         '''
  186.         ''' <param name="throwOnError">
  187.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to directory.
  188.         ''' </param>
  189.         ''' ----------------------------------------------------------------------------------------------------
  190.         ''' <returns>
  191.         ''' An <see cref="IEnumerable(Of DirectoryInfo)"/> instance containing the dirrectories information.
  192.         ''' </returns>
  193.         ''' ----------------------------------------------------------------------------------------------------
  194.         ''' <exception cref="Global.System.ArgumentException">dirPath or searchOption
  195.         ''' </exception>
  196.         ''' ----------------------------------------------------------------------------------------------------
  197.         <DebuggerStepThrough>
  198.         Friend Shared Function GetDirs(ByVal dirPath As String,
  199.                                         ByVal searchOption As SearchOption,
  200.                                         Optional ByVal dirPathPatterns As IEnumerable(Of String) = Nothing,
  201.                                         Optional ByVal dirNamePatterns As IEnumerable(Of String) = Nothing,
  202.                                         Optional ByVal ignoreCase As Boolean = True,
  203.                                         Optional ByVal throwOnError As Boolean = False) As IEnumerable(Of DirectoryInfo)
  204.  
  205.             ' Analyze and resolve path problems. (eg. 'C:' -> 'C:\')
  206.             FileDirSearcher.AnalyzePath(dirPath)
  207.  
  208.             ' Analyze the passed arguments.
  209.             FileDirSearcher.AnalyzeArgs(dirPath, searchOption)
  210.  
  211.             ' Get and return the directories.
  212.             Dim queue As New ConcurrentQueue(Of DirectoryInfo)
  213.             FileDirSearcher.CollectDirs(queue, dirPath, searchOption, dirPathPatterns, dirNamePatterns, ignoreCase, throwOnError)
  214.             Return queue.AsEnumerable
  215.  
  216.         End Function
  217.  
  218.         ''' ----------------------------------------------------------------------------------------------------
  219.         ''' <summary>
  220.         ''' Gets the filepaths those matches the criteria inside the specified directory and/or sub-directories.
  221.         ''' </summary>
  222.         ''' ----------------------------------------------------------------------------------------------------
  223.         ''' <param name="dirPath">
  224.         ''' The root directory path to search for directories.
  225.         ''' </param>
  226.         '''
  227.         ''' <param name="searchOption">
  228.         ''' The searching mode.
  229.         ''' </param>
  230.         '''
  231.         ''' <param name="dirPathPatterns">
  232.         ''' The directory path pattern(s) to match.
  233.         ''' </param>
  234.         '''
  235.         ''' <param name="dirNamePatterns">
  236.         ''' The directory name pattern(s) to match.
  237.         ''' </param>
  238.         '''
  239.         ''' <param name="ignoreCase">
  240.         ''' If <see langword="True"/>, ignores the comparing case of <paramref name="dirPathPatterns"/> and <paramref name="dirNamePatterns"/> patterns.
  241.         ''' </param>
  242.         '''
  243.         ''' <param name="throwOnError">
  244.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to directory.
  245.         ''' </param>
  246.         ''' ----------------------------------------------------------------------------------------------------
  247.         ''' <returns>
  248.         ''' An <see cref="IEnumerable(Of String)"/> instance containing the directory paths.
  249.         ''' </returns>
  250.         ''' ----------------------------------------------------------------------------------------------------
  251.         ''' <exception cref="Global.System.ArgumentException">dirPath or searchOption
  252.         ''' </exception>
  253.         ''' ----------------------------------------------------------------------------------------------------
  254.         <DebuggerStepThrough>
  255.         Friend Shared Function GetDirPaths(ByVal dirPath As String,
  256.                                             ByVal searchOption As SearchOption,
  257.                                             Optional ByVal dirPathPatterns As IEnumerable(Of String) = Nothing,
  258.                                             Optional ByVal dirNamePatterns As IEnumerable(Of String) = Nothing,
  259.                                             Optional ByVal ignoreCase As Boolean = True,
  260.                                             Optional ByVal throwOnError As Boolean = False) As IEnumerable(Of String)
  261.  
  262.             ' Analyze and resolve path problems. (eg. 'C:' -> 'C:\')
  263.             FileDirSearcher.AnalyzePath(dirPath)
  264.  
  265.             ' Analyze the passed arguments.
  266.             FileDirSearcher.AnalyzeArgs(dirPath, searchOption)
  267.  
  268.             ' Get and return the directory paths.
  269.             Dim queue As New ConcurrentQueue(Of String)
  270.             FileDirSearcher.CollectDirPaths(queue, dirPath, searchOption, dirPathPatterns, dirNamePatterns, ignoreCase, throwOnError)
  271.             Return queue.AsEnumerable
  272.  
  273.         End Function
  274.  
  275. #End Region
  276.  
  277. #Region " Private Methods "
  278.  
  279.         ''' ----------------------------------------------------------------------------------------------------
  280.         ''' <summary>
  281.         ''' Analyzes a directory path and perform specific changes on it.
  282.         ''' </summary>
  283.         ''' ----------------------------------------------------------------------------------------------------
  284.         ''' <param name="refDirPath">
  285.         ''' The directory path.
  286.         ''' </param>
  287.         ''' ----------------------------------------------------------------------------------------------------
  288.         ''' <exception cref="Global.System.ArgumentNullException">dirPath;Value is null, empty, or white-spaced.
  289.         ''' </exception>
  290.         ''' ----------------------------------------------------------------------------------------------------
  291.         <DebuggerStepThrough>
  292.         Private Shared Sub AnalyzePath(ByRef refDirPath As String)
  293.  
  294.             If String.IsNullOrEmpty(refDirPath) OrElse String.IsNullOrWhiteSpace(refDirPath) Then
  295.                 Throw New ArgumentNullException("dirPath", "Value is null, empty, or white-spaced.")
  296.  
  297.             Else
  298.                 ' Trim unwanted characters.
  299.                 refDirPath = refDirPath.TrimStart({" "c}).TrimEnd({" "c})
  300.  
  301.                 If Path.IsPathRooted(refDirPath) Then
  302.                     ' The root paths contained on the returned FileInfo objects will start with the same string-case as this root path.
  303.                     ' So just for a little visual improvement, I'll treat this root path as a Drive-Letter and I convert it to UpperCase.
  304.                     refDirPath = Char.ToUpper(refDirPath.First()) & refDirPath.Substring(1)
  305.                 End If
  306.  
  307.                 If Not refDirPath.EndsWith("\"c) Then
  308.                     ' Possibly its a drive letter without backslash ('C:') or else just a normal path without backslash ('C\Dir').
  309.                     ' In any case, fix the ending backslash.
  310.                     refDirPath = refDirPath.Insert(refDirPath.Length, "\"c)
  311.                 End If
  312.  
  313.             End If
  314.  
  315.         End Sub
  316.  
  317.         ''' ----------------------------------------------------------------------------------------------------
  318.         ''' <summary>
  319.         ''' Analyzes the specified directory values.
  320.         ''' </summary>
  321.         ''' ----------------------------------------------------------------------------------------------------
  322.         ''' <param name="dirPath">
  323.         ''' The root directory path to search for files.
  324.         ''' </param>
  325.         '''
  326.         ''' <param name="searchOption">
  327.         ''' The searching mode.
  328.         ''' </param>
  329.         ''' ----------------------------------------------------------------------------------------------------
  330.         ''' <exception cref="Global.System.ArgumentException">dirPath or searchOption
  331.         ''' </exception>
  332.         ''' ----------------------------------------------------------------------------------------------------
  333.         <DebuggerStepThrough>
  334.         Private Shared Sub AnalyzeArgs(ByVal dirPath As String, ByVal searchOption As SearchOption)
  335.  
  336.             If Not Directory.Exists(dirPath) Then
  337.                 Throw New ArgumentException(String.Format("Directory doesn't exists: '{0}'", dirPath), "dirPath")
  338.  
  339.             ElseIf (searchOption <> SearchOption.TopDirectoryOnly) AndAlso (searchOption <> SearchOption.AllDirectories) Then
  340.                 Throw New ArgumentException(String.Format("Value of '{0}' is not valid enumeration value.", CStr(searchOption)), "searchOption")
  341.  
  342.             End If
  343.  
  344.         End Sub
  345.  
  346.         ''' ----------------------------------------------------------------------------------------------------
  347.         ''' <summary>
  348.         ''' Tries to instance the by-reference <see cref="DirectoryInfo"/> object using the given directory path.
  349.         ''' </summary>
  350.         ''' ----------------------------------------------------------------------------------------------------
  351.         ''' <param name="dirPath">
  352.         ''' The directory path used to instance the by-reference <see cref="DirectoryInfo"/> object.
  353.         ''' </param>
  354.         '''
  355.         ''' <param name="refDirInfo">
  356.         ''' The by-reference <see cref="DirectoryInfo"/> object to instance it using the given directory path.
  357.         ''' </param>
  358.         '''
  359.         ''' <param name="throwOnError">
  360.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to directory.
  361.         ''' </param>
  362.         ''' ----------------------------------------------------------------------------------------------------
  363.         <DebuggerStepThrough>
  364.         Private Shared Sub SetupDirInfoObject(ByVal dirPath As String,
  365.                                               ByRef refDirInfo As DirectoryInfo,
  366.                                               ByVal throwOnError As Boolean)
  367.  
  368.             Try
  369.                 refDirInfo = New DirectoryInfo(dirPath)
  370.  
  371.             Catch ex As Exception
  372.  
  373.                 Select Case ex.GetType() ' Handle or suppress exceptions by its type,
  374.  
  375.                     ' I've wrote different types just to feel free to expand this feature in the future.
  376.                     Case GetType(ArgumentNullException),
  377.                          GetType(ArgumentException),
  378.                          GetType(SecurityException),
  379.                          GetType(PathTooLongException),
  380.                          ex.GetType()
  381.  
  382.                         If (throwOnError) Then
  383.                             Throw
  384.                         End If
  385.  
  386.                 End Select
  387.  
  388.             End Try
  389.  
  390.         End Sub
  391.  
  392.         ''' ----------------------------------------------------------------------------------------------------
  393.         ''' <summary>
  394.         ''' Tries to instance the by-reference <paramref name="refCol"/> object using the given directory path.
  395.         ''' </summary>
  396.         ''' ----------------------------------------------------------------------------------------------------
  397.         ''' <typeparam name="A">
  398.         ''' The type of the <paramref name="refCol"/> object used to cast and fill the by-reference collection.
  399.         ''' </typeparam>
  400.         '''
  401.         ''' <param name="objectAction">
  402.         ''' The method to invoke, only for <see cref="FileInfo"/> or <see cref="DirectoryInfo"/> objects, this parameter can be <see langword="Nothing"/>.
  403.         ''' </param>
  404.         '''
  405.         ''' <param name="sharedAction">
  406.         ''' The method to invoke, only for filepaths or directorypaths, this parameter can be <see langword="Nothing"/>.
  407.         ''' </param>
  408.         '''
  409.         ''' <param name="dirPath">
  410.         ''' The directory path used to instance the by-reference <paramref name="refCol"/> object.
  411.         ''' </param>
  412.         '''
  413.         ''' <param name="searchPattern">
  414.         ''' The search pattern to list files or directories.
  415.         ''' </param>
  416.         '''
  417.         ''' <param name="refCol">
  418.         ''' The by-reference <see cref="IEnumerable(Of A)"/> object to instance it using the given directory path.
  419.         ''' </param>
  420.         '''
  421.         ''' <param name="throwOnError">
  422.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to file or directory.
  423.         ''' </param>
  424.         ''' ----------------------------------------------------------------------------------------------------
  425.         <DebuggerStepThrough>
  426.         Private Shared Sub SetupFileDirCollection(Of A)(ByVal objectAction As Func(Of String, SearchOption, IEnumerable(Of A)),
  427.                                                         ByVal sharedAction As Func(Of String, String, SearchOption, IEnumerable(Of A)),
  428.                                                         ByVal dirPath As String,
  429.                                                         ByVal searchPattern As String,
  430.                                                         ByRef refCol As IEnumerable(Of A),
  431.                                                         ByVal throwOnError As Boolean)
  432.  
  433.             Try
  434.                 If (objectAction IsNot Nothing) Then
  435.                     refCol = objectAction.Invoke(searchPattern, SearchOption.TopDirectoryOnly)
  436.  
  437.                 ElseIf (sharedAction IsNot Nothing) Then
  438.                     refCol = sharedAction.Invoke(dirPath, searchPattern, SearchOption.TopDirectoryOnly)
  439.  
  440.                 Else
  441.                     Throw New ArgumentException("Any Action has been defined.")
  442.  
  443.                 End If
  444.  
  445.             Catch ex As Exception
  446.  
  447.                 Select Case ex.GetType ' Handle or suppress exceptions by its type,
  448.  
  449.                     ' I've wrote different types just to feel free to expand this feature in the future.
  450.                     Case GetType(UnauthorizedAccessException),
  451.                          GetType(DirectoryNotFoundException),
  452.                          ex.GetType()
  453.  
  454.                         If (throwOnError) Then
  455.                             Throw
  456.                         End If
  457.  
  458.                 End Select
  459.  
  460.             End Try
  461.  
  462.         End Sub
  463.  
  464.         ''' ----------------------------------------------------------------------------------------------------
  465.         ''' <summary>
  466.         ''' Determines whether at least one of the specified patterns matches the given value.
  467.         ''' </summary>
  468.         ''' ----------------------------------------------------------------------------------------------------
  469.         ''' <param name="value">
  470.         ''' The value, which can be a filename, file extension, direcrory path, or directory name.
  471.         ''' </param>
  472.         '''
  473.         ''' <param name="patterns">
  474.         ''' The patterns to match the given value.
  475.         ''' </param>
  476.         '''
  477.         ''' <param name="ignoreCase">
  478.         ''' If set to <see langword="True"/>, compares ignoring string-case rules.
  479.         ''' </param>
  480.         ''' ----------------------------------------------------------------------------------------------------
  481.         ''' <returns>
  482.         ''' <see langword="True"/> at least one of the specified patterns matches the given value; <see langword="False"/> otherwise.
  483.         ''' </returns>
  484.         ''' ----------------------------------------------------------------------------------------------------
  485.         <DebuggerStepThrough>
  486.         Private Shared Function IsMatchPattern(ByVal value As String,
  487.                                                ByVal patterns As IEnumerable(Of String),
  488.                                                ByVal ignoreCase As Boolean) As Boolean
  489.  
  490.             ' Iterate the filename pattern(s) to match each name pattern on the current name.
  491.             For Each pattern As String In patterns
  492.  
  493.                 ' Supress consecuent conditionals if pattern its an asterisk.
  494.                 If pattern.Equals("*", StringComparison.OrdinalIgnoreCase) Then
  495.                     Return True
  496.  
  497.                 ElseIf (ignoreCase) Then ' Compare name ignoring string-case rules.
  498.                     If value.ToLower Like pattern.ToLower Then
  499.                         Return True
  500.                     End If
  501.  
  502.                 Else ' Compare filename unignoring string-case rules.
  503.                     If value Like pattern Then
  504.                         Return True
  505.                     End If
  506.  
  507.                 End If ' ignoreCase
  508.  
  509.             Next pattern
  510.  
  511.             Return False
  512.  
  513.         End Function
  514.  
  515.         ''' ----------------------------------------------------------------------------------------------------
  516.         ''' <summary>
  517.         ''' Runs the next collector tasks synchronouslly.
  518.         ''' </summary>
  519.         ''' ----------------------------------------------------------------------------------------------------
  520.         ''' <typeparam name="T"></typeparam>
  521.         ''' <param name="action">
  522.         ''' The collector method to invoke.
  523.         ''' </param>
  524.         '''
  525.         ''' <param name="queue">
  526.         ''' The <see cref="ConcurrentQueue(Of FileInfo)"/> instance.
  527.         ''' </param>
  528.         '''
  529.         ''' <param name="dirPath">
  530.         ''' The directory path.
  531.         ''' </param>
  532.         '''
  533.         ''' <param name="firstPatterns">
  534.         ''' The first comparison patterns.
  535.         ''' </param>
  536.         '''
  537.         ''' <param name="secondPatterns">
  538.         ''' The second comparison patterns.
  539.         ''' </param>
  540.         '''
  541.         ''' <param name="ignoreCase">
  542.         ''' If set to <see langword="True"/>, compares ignoring string-case rules.
  543.         ''' </param>
  544.         '''
  545.         ''' <param name="throwOnError">
  546.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to file or directory.
  547.         ''' </param>
  548.         ''' ----------------------------------------------------------------------------------------------------
  549.         <DebuggerStepThrough>
  550.         Private Shared Sub RunNextTasks(Of T)(ByVal action As Action(Of ConcurrentQueue(Of T), String, SearchOption, IEnumerable(Of String), IEnumerable(Of String), Boolean, Boolean),
  551.                                               ByVal queue As ConcurrentQueue(Of T),
  552.                                               ByVal dirPath As String,
  553.                                               ByVal firstPatterns As IEnumerable(Of String),
  554.                                               ByVal secondPatterns As IEnumerable(Of String),
  555.                                               ByVal ignoreCase As Boolean,
  556.                                               ByVal throwOnError As Boolean)
  557.  
  558.             Try
  559.                 Task.WaitAll(New DirectoryInfo(dirPath).
  560.                                  GetDirectories.
  561.                                  Select(Function(dir As DirectoryInfo)
  562.                                             Return Task.Factory.StartNew(
  563.                                             Sub()
  564.                                                 action.Invoke(queue,
  565.                                                               dir.FullName, SearchOption.AllDirectories,
  566.                                                               firstPatterns, secondPatterns,
  567.                                                               ignoreCase, throwOnError)
  568.                                             End Sub)
  569.                                         End Function).ToArray())
  570.  
  571.             Catch ex As Exception
  572.  
  573.                 Select Case ex.GetType ' Handle or suppress exceptions by its type,
  574.  
  575.                     ' I've wrote different types just to feel free to expand this feature in the future.
  576.                     Case GetType(UnauthorizedAccessException),
  577.                          GetType(DirectoryNotFoundException),
  578.                          ex.GetType()
  579.  
  580.                         If (throwOnError) Then
  581.                             Throw
  582.                         End If
  583.  
  584.                 End Select
  585.  
  586.             End Try
  587.  
  588.         End Sub
  589.  
  590.         ''' ----------------------------------------------------------------------------------------------------
  591.         ''' <summary>
  592.         ''' Collects the files those matches the criteria inside the specified directory and/or sub-directories.
  593.         ''' </summary>
  594.         ''' ----------------------------------------------------------------------------------------------------
  595.         ''' <param name="queue">
  596.         ''' The <see cref="ConcurrentQueue(Of FileInfo)"/> instance to enqueue new files.
  597.         ''' </param>
  598.         '''
  599.         ''' <param name="dirPath">
  600.         ''' The root directory path to search for files.
  601.         ''' </param>
  602.         '''
  603.         ''' <param name="searchOption">
  604.         ''' The searching mode.
  605.         ''' </param>
  606.         '''
  607.         ''' <param name="fileNamePatterns">
  608.         ''' The file name pattern(s) to match.
  609.         ''' </param>
  610.         '''
  611.         ''' <param name="fileExtPatterns">
  612.         ''' The file extension pattern(s) to match.
  613.         ''' </param>
  614.         '''
  615.         ''' <param name="ignoreCase">
  616.         ''' If <see langword="True"/>, ignores the comparing case of <paramref name="fileNamePatterns"/> and <paramref name="fileExtPatterns"/> patterns.
  617.         ''' </param>
  618.         '''
  619.         ''' <param name="throwOnError">
  620.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to file or directory.
  621.         ''' </param>
  622.         ''' ----------------------------------------------------------------------------------------------------
  623.         <DebuggerStepThrough>
  624.         Private Shared Sub CollectFiles(ByVal queue As ConcurrentQueue(Of FileInfo),
  625.                                         ByVal dirPath As String,
  626.                                         ByVal searchOption As SearchOption,
  627.                                         ByVal fileNamePatterns As IEnumerable(Of String),
  628.                                         ByVal fileExtPatterns As IEnumerable(Of String),
  629.                                         ByVal ignoreCase As Boolean,
  630.                                         ByVal throwOnError As Boolean)
  631.  
  632.             ' Initialize a FileInfo collection.
  633.             Dim fileInfoCol As IEnumerable(Of FileInfo) = Nothing
  634.  
  635.             ' Initialize a DirectoryInfo.
  636.             Dim dirInfo As DirectoryInfo = Nothing
  637.             FileDirSearcher.SetupDirInfoObject(dirPath, dirInfo, throwOnError)
  638.  
  639.             If (fileExtPatterns IsNot Nothing) Then
  640.                 ' Decrease time execution by searching for files that has extension.
  641.                 FileDirSearcher.SetupFileDirCollection(Of FileInfo)(AddressOf dirInfo.GetFiles, Nothing,
  642.                                                                     dirInfo.FullName, "*.*", fileInfoCol, throwOnError)
  643.             Else
  644.                 ' Search for all files.
  645.                 FileDirSearcher.SetupFileDirCollection(Of FileInfo)(AddressOf dirInfo.GetFiles, Nothing,
  646.                                                                     dirInfo.FullName, "*", fileInfoCol, throwOnError)
  647.             End If
  648.  
  649.             ' If the fileInfoCol collection is not empty then...
  650.             If (fileInfoCol IsNot Nothing) Then
  651.  
  652.                 ' Iterate the files.
  653.                 For Each fInfo As FileInfo In fileInfoCol
  654.  
  655.                     ' Flag to determine whether a filename pattern is matched. Activated by default.
  656.                     Dim flagNamePattern As Boolean = True
  657.  
  658.                     ' Flag to determine whether a file extension pattern is matched. Activated by default.
  659.                     Dim flagExtPattern As Boolean = True
  660.  
  661.                     ' If filename patterns collection is not empty then...
  662.                     If (fileNamePatterns IsNot Nothing) Then
  663.                         flagNamePattern = IsMatchPattern(fInfo.Name, fileNamePatterns, ignoreCase)
  664.                     End If
  665.  
  666.                     ' If file extension patterns collection is not empty then...
  667.                     If (fileExtPatterns IsNot Nothing) Then
  668.                         flagExtPattern = IsMatchPattern(fInfo.Extension, fileExtPatterns, ignoreCase)
  669.                     End If
  670.  
  671.                     ' If fileName and also fileExtension patterns are matched then...
  672.                     If (flagNamePattern AndAlso flagExtPattern) Then
  673.                         queue.Enqueue(fInfo) ' Enqueue this FileInfo object.
  674.                     End If
  675.  
  676.                 Next fInfo
  677.  
  678.             End If ' fileInfoCol IsNot Nothing
  679.  
  680.             ' If searchOption is recursive then...
  681.             If (searchOption = SearchOption.AllDirectories) Then
  682.                 RunNextTasks(Of FileInfo)(AddressOf CollectFiles, queue, dirInfo.FullName, fileNamePatterns, fileExtPatterns, ignoreCase, throwOnError)
  683.             End If
  684.  
  685.         End Sub
  686.  
  687.         ''' ----------------------------------------------------------------------------------------------------
  688.         ''' <summary>
  689.         ''' Collects the filepaths those matches the criteria inside the specified directory and/or sub-directories.
  690.         ''' </summary>
  691.         ''' ----------------------------------------------------------------------------------------------------
  692.         ''' <param name="queue">
  693.         ''' The <see cref="ConcurrentQueue(Of String)"/> instance to enqueue new filepaths.
  694.         ''' </param>
  695.         '''
  696.         ''' <param name="dirPath">
  697.         ''' The root directory path to search for files.
  698.         ''' </param>
  699.         '''
  700.         ''' <param name="searchOption">
  701.         ''' The searching mode.
  702.         ''' </param>
  703.         '''
  704.         ''' <param name="fileNamePatterns">
  705.         ''' The file name pattern(s) to match.
  706.         ''' </param>
  707.         '''
  708.         ''' <param name="fileExtPatterns">
  709.         ''' The file extension pattern(s) to match.
  710.         ''' </param>
  711.         '''
  712.         ''' <param name="ignoreCase">
  713.         ''' If <see langword="True"/>, ignores the comparing case of <paramref name="fileNamePatterns"/> and <paramref name="fileExtPatterns"/> patterns.
  714.         ''' </param>
  715.         '''
  716.         ''' <param name="throwOnError">
  717.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to file or directory.
  718.         ''' </param>
  719.         ''' ----------------------------------------------------------------------------------------------------
  720.         <DebuggerStepThrough>
  721.         Private Shared Sub CollectFilePaths(ByVal queue As ConcurrentQueue(Of String),
  722.                                             ByVal dirPath As String,
  723.                                             ByVal searchOption As SearchOption,
  724.                                             ByVal fileNamePatterns As IEnumerable(Of String),
  725.                                             ByVal fileExtPatterns As IEnumerable(Of String),
  726.                                             ByVal ignoreCase As Boolean,
  727.                                             ByVal throwOnError As Boolean)
  728.  
  729.             ' Initialize a filepath collection.
  730.             Dim filePathCol As IEnumerable(Of String) = Nothing
  731.  
  732.             If (fileExtPatterns IsNot Nothing) Then
  733.                 ' Decrease time execution by searching for files that has extension.
  734.                 FileDirSearcher.SetupFileDirCollection(Of String)(Nothing, AddressOf Directory.GetFiles,
  735.                                                                   dirPath, "*.*", filePathCol, throwOnError)
  736.             Else
  737.                 ' Search for all files.
  738.                 FileDirSearcher.SetupFileDirCollection(Of String)(Nothing, AddressOf Directory.GetFiles,
  739.                                                                   dirPath, "*", filePathCol, throwOnError)
  740.             End If
  741.  
  742.             ' If the filepath collection is not empty then...
  743.             If filePathCol IsNot Nothing Then
  744.  
  745.                 ' Iterate the filepaths.
  746.                 For Each filePath As String In filePathCol
  747.  
  748.                     ' Flag to determine whether a filename pattern is matched. Activated by default.
  749.                     Dim flagNamePattern As Boolean = True
  750.  
  751.                     ' Flag to determine whether a file extension pattern is matched. Activated by default.
  752.                     Dim flagExtPattern As Boolean = True
  753.  
  754.                     ' If filename patterns collection is not empty then...
  755.                     If (fileNamePatterns IsNot Nothing) Then
  756.                         flagNamePattern = IsMatchPattern(Path.GetFileNameWithoutExtension(filePath), fileNamePatterns, ignoreCase)
  757.                     End If
  758.  
  759.                     ' If file extension patterns collection is not empty then...
  760.                     If (fileExtPatterns IsNot Nothing) Then
  761.                         flagExtPattern = IsMatchPattern(Path.GetExtension(filePath), fileExtPatterns, ignoreCase)
  762.                     End If
  763.  
  764.                     ' If fileName and also fileExtension patterns are matched then...
  765.                     If (flagNamePattern AndAlso flagExtPattern) Then
  766.                         queue.Enqueue(filePath) ' Enqueue this filepath.
  767.                     End If
  768.  
  769.                 Next filePath
  770.  
  771.             End If ' filePathCol IsNot Nothing
  772.  
  773.             ' If searchOption is recursive then...
  774.             If (searchOption = SearchOption.AllDirectories) Then
  775.                 RunNextTasks(Of String)(AddressOf CollectFilePaths, queue, dirPath, fileNamePatterns, fileExtPatterns, ignoreCase, throwOnError)
  776.             End If
  777.  
  778.         End Sub
  779.  
  780.         ''' ----------------------------------------------------------------------------------------------------
  781.         ''' <summary>
  782.         ''' Collects the directories those matches the criteria inside the specified directory and/or sub-directories.
  783.         ''' </summary>
  784.         ''' ----------------------------------------------------------------------------------------------------
  785.         ''' <param name="queue">
  786.         ''' The <see cref="ConcurrentQueue(Of DirectoryInfo)"/> instance to enqueue new directories.
  787.         ''' </param>
  788.         '''
  789.         ''' <param name="dirPath">
  790.         ''' The root directory path to search for directories.
  791.         ''' </param>
  792.         '''
  793.         ''' <param name="searchOption">
  794.         ''' The searching mode.
  795.         ''' </param>
  796.         '''
  797.         ''' <param name="dirPathPatterns">
  798.         ''' The directory path pattern(s) to match.
  799.         ''' </param>
  800.         '''
  801.         ''' <param name="dirNamePatterns">
  802.         ''' The directory name pattern(s) to match.
  803.         ''' </param>
  804.         '''
  805.         ''' <param name="ignoreCase">
  806.         ''' If <see langword="True"/>, ignores the comparing case of <paramref name="dirPathPatterns"/> and <paramref name="dirNamePatterns"/> patterns.
  807.         ''' </param>
  808.         '''
  809.         ''' <param name="throwOnError">
  810.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to directory.
  811.         ''' </param>
  812.         ''' ----------------------------------------------------------------------------------------------------
  813.         <DebuggerStepThrough>
  814.         Private Shared Sub CollectDirs(ByVal queue As ConcurrentQueue(Of DirectoryInfo),
  815.                                        ByVal dirPath As String,
  816.                                        ByVal searchOption As SearchOption,
  817.                                        ByVal dirPathPatterns As IEnumerable(Of String),
  818.                                        ByVal dirNamePatterns As IEnumerable(Of String),
  819.                                        ByVal ignoreCase As Boolean,
  820.                                        ByVal throwOnError As Boolean)
  821.  
  822.             ' Initialize a DirectoryInfo collection.
  823.             Dim dirInfoCol As IEnumerable(Of DirectoryInfo) = Nothing
  824.  
  825.             ' Initialize a DirectoryInfo.
  826.             Dim dirInfo As DirectoryInfo = Nothing
  827.             FileDirSearcher.SetupDirInfoObject(dirPath, dirInfo, throwOnError)
  828.  
  829.             ' Get the top directories of the current directory.
  830.             FileDirSearcher.SetupFileDirCollection(Of DirectoryInfo)(AddressOf dirInfo.GetDirectories,
  831.                                                                      Nothing, dirInfo.FullName, "*", dirInfoCol, throwOnError)
  832.  
  833.             ' If the fileInfoCol collection is not empty then...
  834.             If (dirInfoCol IsNot Nothing) Then
  835.  
  836.                 ' Iterate the files.
  837.                 For Each dir As DirectoryInfo In dirInfoCol
  838.  
  839.                     ' Flag to determine whether a directory path pattern is matched. Activated by default.
  840.                     Dim flagPathPattern As Boolean = True
  841.  
  842.                     ' Flag to determine whether a directory name pattern is matched. Activated by default.
  843.                     Dim flagNamePattern As Boolean = True
  844.  
  845.                     ' If directory path patterns collection is not empty then...
  846.                     If (dirPathPatterns IsNot Nothing) Then
  847.                         flagPathPattern = IsMatchPattern(dir.FullName, dirPathPatterns, ignoreCase)
  848.                     End If
  849.  
  850.                     ' If directory name patterns collection is not empty then...
  851.                     If (dirNamePatterns IsNot Nothing) Then
  852.                         flagNamePattern = IsMatchPattern(dir.Name, dirNamePatterns, ignoreCase)
  853.                     End If
  854.  
  855.                     ' If directory path and also directory name patterns are matched then...
  856.                     If (flagPathPattern AndAlso flagNamePattern) Then
  857.                         queue.Enqueue(dir) ' Enqueue this DirectoryInfo object.
  858.                     End If
  859.  
  860.                 Next dir
  861.  
  862.             End If ' dirInfoCol IsNot Nothing
  863.  
  864.             ' If searchOption is recursive then...
  865.             If (searchOption = SearchOption.AllDirectories) Then
  866.                 RunNextTasks(Of DirectoryInfo)(AddressOf CollectDirs, queue, dirPath, dirPathPatterns, dirNamePatterns, ignoreCase, throwOnError)
  867.             End If
  868.  
  869.         End Sub
  870.  
  871.         ''' ----------------------------------------------------------------------------------------------------
  872.         ''' <summary>
  873.         ''' Collects the directory paths those matches the criteria inside the specified directory and/or sub-directories.
  874.         ''' </summary>
  875.         ''' ----------------------------------------------------------------------------------------------------
  876.         ''' <param name="queue">
  877.         ''' The <see cref="ConcurrentQueue(Of String)"/> instance to enqueue new directory paths.
  878.         ''' </param>
  879.         '''
  880.         ''' <param name="dirPath">
  881.         ''' The root directory path to search for directories.
  882.         ''' </param>
  883.         '''
  884.         ''' <param name="searchOption">
  885.         ''' The searching mode.
  886.         ''' </param>
  887.         '''
  888.         ''' <param name="dirPathPatterns">
  889.         ''' The directory path pattern(s) to match.
  890.         ''' </param>
  891.         '''
  892.         ''' <param name="dirNamePatterns">
  893.         ''' The directory name pattern(s) to match.
  894.         ''' </param>
  895.         '''
  896.         ''' <param name="ignoreCase">
  897.         ''' If <see langword="True"/>, ignores the comparing case of <paramref name="dirPathPatterns"/> and <paramref name="dirNamePatterns"/> patterns.
  898.         ''' </param>
  899.         '''
  900.         ''' <param name="throwOnError">
  901.         ''' If set to <see langword="True"/>, exceptions will be thrown, like access denied to directory.
  902.         ''' </param>
  903.         ''' ----------------------------------------------------------------------------------------------------
  904.         <DebuggerStepThrough>
  905.         Private Shared Sub CollectDirPaths(ByVal queue As ConcurrentQueue(Of String),
  906.                                            ByVal dirPath As String,
  907.                                            ByVal searchOption As SearchOption,
  908.                                            ByVal dirPathPatterns As IEnumerable(Of String),
  909.                                            ByVal dirNamePatterns As IEnumerable(Of String),
  910.                                            ByVal ignoreCase As Boolean,
  911.                                            ByVal throwOnError As Boolean)
  912.  
  913.             ' Initialize a directory paths collection.
  914.             Dim dirPathCol As IEnumerable(Of String) = Nothing
  915.  
  916.             ' Get the top directory paths of the current directory.
  917.             FileDirSearcher.SetupFileDirCollection(Of String)(Nothing, AddressOf Directory.GetDirectories, dirPath, "*", dirPathCol, throwOnError)
  918.  
  919.             ' If the fileInfoCol collection is not empty then...
  920.             If (dirPathCol IsNot Nothing) Then
  921.  
  922.                 ' Iterate the files.
  923.                 For Each dir As String In dirPathCol
  924.  
  925.                     ' Flag to determine whether a directory path pattern is matched. Activated by default.
  926.                     Dim flagPathPattern As Boolean = True
  927.  
  928.                     ' Flag to determine whether a directory name pattern is matched. Activated by default.
  929.                     Dim flagNamePattern As Boolean = True
  930.  
  931.                     ' If directory path patterns collection is not empty then...
  932.                     If (dirPathPatterns IsNot Nothing) Then
  933.                         flagPathPattern = IsMatchPattern(dir, dirPathPatterns, ignoreCase)
  934.                     End If
  935.  
  936.                     ' If directory name patterns collection is not empty then...
  937.                     If (dirNamePatterns IsNot Nothing) Then
  938.                         flagNamePattern = IsMatchPattern(Path.GetFileName(dir), dirNamePatterns, ignoreCase)
  939.                     End If
  940.  
  941.                     ' If directory path and also directory name patterns are matched then...
  942.                     If (flagPathPattern AndAlso flagNamePattern) Then
  943.                         queue.Enqueue(dir) ' Enqueue this directory path.
  944.                     End If
  945.  
  946.                 Next dir
  947.  
  948.             End If ' dirPathCol IsNot Nothing
  949.  
  950.             ' If searchOption is recursive then...
  951.             If (searchOption = SearchOption.AllDirectories) Then
  952.                 RunNextTasks(Of String)(AddressOf CollectDirPaths, queue, dirPath, dirPathPatterns, dirNamePatterns, ignoreCase, throwOnError)
  953.             End If
  954.  
  955.         End Sub
  956.  
  957. #End Region
  958.  
  959.     End Class
  960.  
  961. 'End Namespace
  962.  
  963. #End Region
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement