''' <summary>
''' Finds a file whose name matches a pattern.
''' </summary>
''' <param name="path">
''' The root folder in which to search.
''' </param>
''' <param name="searchPattern">
''' The pattern to match to the file name.
''' </param>
''' <returns>
''' The fully path of the file if one is found; otherwise, a null reference.
''' </returns>
''' <remarks>
''' Performs a breadth-first search.
''' </remarks>
Public Function FindFile(path As String, searchPattern As String) As String
Return FindFile(path, searchPattern, SearchMode.BreadthFirst, Nothing)
End Function
''' <summary>
''' Finds a file whose name matches a pattern.
''' </summary>
''' <param name="path">
''' The root folder in which to search.
''' </param>
''' <param name="searchPattern">
''' The pattern to match to the file name.
''' </param>
''' <param name="mode">
''' A value indicating the type of search to perform: breadth-first or depth first.
''' </param>
''' <returns>
''' The fully path of the file if one is found; otherwise, a null reference.
''' </returns>
Public Function FindFile(path As String, searchPattern As String, mode As SearchMode) As String
Return FindFile(path, searchPattern, mode, Nothing)
End Function
''' <summary>
''' Finds a file whose name matches a pattern.
''' </summary>
''' <param name="path">
''' The root folder in which to search.
''' </param>
''' <param name="searchPattern">
''' The pattern to match to the file name.
''' </param>
''' <param name="maxDepth">
''' The maximum depth of the subfolders to search or a null reference to search all subfolders.
''' </param>
''' <returns>
''' The fully path of the file if one is found; otherwise, a null reference.
''' </returns>
''' <remarks>
''' Performs a breadth-first search.
''' </remarks>
Public Function FindFile(path As String, searchPattern As String, maxDepth As UInteger?) As String
Return FindFile(path, searchPattern, SearchMode.BreadthFirst, maxDepth)
End Function
''' <summary>
''' Finds a file whose name matches a pattern.
''' </summary>
''' <param name="path">
''' The root folder in which to search.
''' </param>
''' <param name="searchPattern">
''' The pattern to match to the file name.
''' </param>
''' <param name="mode">
''' A value indicating the type of search to perform: breadth-first or depth first.
''' </param>
''' <param name="maxDepth">
''' The maximum depth of the subfolders to search or a null reference to search all subfolders.
''' </param>
''' <returns>
''' The fully path of the file if one is found; otherwise, a null reference.
''' </returns>
Public Function FindFile(path As String, searchPattern As String, mode As SearchMode, maxDepth As UInteger?) As String
Dim filePath As String = Nothing
Select Case mode
Case SearchMode.BreadthFirst
filePath = Directory.GetFiles(path, searchPattern).FirstOrDefault()
If filePath Is Nothing Then
filePath = FindFileBreadthFirst(path, searchPattern, maxDepth)
End If
Case SearchMode.DepthFirst
filePath = FindFileDepthFirst(path, searchPattern, maxDepth)
End Select
Return filePath
End Function
''' <summary>
''' Finds a file whose name matches a pattern by performing a breadth-first search.
''' </summary>
''' <param name="path">
''' The root folder in which to search.
''' </param>
''' <param name="searchPattern">
''' The pattern to match to the file name.
''' </param>
''' <param name="maxDepth">
''' The maximum depth of the subfolders to search or a null reference to search all subfolders.
''' </param>
''' <returns>
''' The fully path of the file if one is found; otherwise, a null reference.
''' </returns>
Private Function FindFileBreadthFirst(path As String, searchPattern As String, maxDepth As UInteger?) As String
Dim filePath As String = Nothing
'Only search subfolders if we have not exceeded the maximum depth.
If Not maxDepth.HasValue OrElse maxDepth.Value > 0 Then
Try
Dim subfolderPaths = Directory.GetDirectories(path)
'Search the top level of each subfolder first.
For Each subfolderPath In subfolderPaths
filePath = Directory.GetFiles(subfolderPath, searchPattern).FirstOrDefault()
'Stop if a match is found.
If filePath IsNot Nothing Then
Exit For
End If
Next
'Continue deeper if a match has not been found.
If filePath Is Nothing Then
If maxDepth.HasValue Then
'We're going one level deeper.
maxDepth -= 1UI
End If
'Search subfolders of each subfolder.
For Each subfolderPath In subfolderPaths
filePath = FindFileBreadthFirst(subfolderPath,
searchPattern,
maxDepth)
'Stop if a match is found.
If filePath IsNot Nothing Then
Exit For
End If
Next
End If
Catch ex As UnauthorizedAccessException
'Ignore an inaccessible folder and continue.
End Try
End If
Return filePath
End Function
''' <summary>
''' Finds a file whose name matches a pattern by performing a depth-first search.
''' </summary>
''' <param name="path">
''' The root folder in which to search.
''' </param>
''' <param name="searchPattern">
''' The pattern to match to the file name.
''' </param>
''' <param name="maxDepth">
''' The maximum depth of the subfolders to search or a null reference to search all subfolders.
''' </param>
''' <returns>
''' The fully path of the file if one is found; otherwise, a null reference.
''' </returns>
Private Function FindFileDepthFirst(path As String, searchPattern As String, maxDepth As UInteger?) As String
Dim filePath As String = Nothing
Try
'Search the current folder first.
filePath = Directory.GetFiles(path, searchPattern).FirstOrDefault()
'Only search subfolders if we have not exceeded the maximum depth.
If filePath Is Nothing AndAlso (Not maxDepth.HasValue OrElse maxDepth.Value > 0) Then
If maxDepth.HasValue Then
'We're going one level deeper.
maxDepth -= 1UI
End If
'Search each subfolder.
For Each subfolderPath In Directory.GetDirectories(path)
filePath = FindFileDepthFirst(subfolderPath,
searchPattern,
maxDepth)
'Stop if a match is found.
If filePath IsNot Nothing Then
Exit For
End If
Next
End If
Catch ex As UnauthorizedAccessException
'Ignore an inaccessible folder and continue.
End Try
Return filePath
End Function