Reputation: 15
I have string say "c:\debug\ *.txt" In Debug folder there are severeal .txt files , say test1.txt test2.txt test3.txt .
How can I get from this string c:\debug\ *.txt an array of wildcard files?
a(0)=c:\debug\test1.txt
a(1)=c:\debug\test2.txt
a(2)=c:\debug\test3.txt
It is also possible that the string would be something like "C:\logs\12*\ *.log"
a(0)=C:\logs\120114\01.log
a(0)=C:\logs\120114\02.log
a(0)=C:\logs\120114\03.log
etc.
Anyone have any ideas on this?
Upvotes: 0
Views: 5858
Reputation: 23
You could use the 'Like' keyword:
' For your example, call this function with root = "C:\logs" and wild = "12*\*.log"
Friend Function GetMyFiles(root As String, wild As String, Optional allowsub As Boolean = True) As List(Of String)
Dim a As New List(Of String), pattern As String
' ensure root ends with a \
If Not root.EndsWith("\") Then root &= "\"
' the extra * allows for subdirectories in between, if required
pattern = root & If(allowsub, "*", "") & wild
For Each f As String In My.Computer.FileSystem.GetFiles(root, FileIO.SearchOption.SearchAllSubDirectories)
If f Like pattern Then a.Add(f)
Next
Return a
End Function
Of course, if you hit a protected system directory, it'll fail.
This function is just to demonstrate the 'Like' keyword.
It will work if 'root' isn't a drive root (e.g. C:).
Done properly, a separate function would collect directories first, each tested for access permissions in a Try/Catch block. Here's how that looks:
Friend Function GetAllAccessibleDirs(ByRef Dir As String, Optional inclDir As Boolean = True, Optional Sort As Boolean = False) As List(Of String)
Dim D As New List(Of String), Q As New Queue(Of String), dummy As DirectoryInfo, s As String
If inclDir Then D.Add(Dir)
Q.Enqueue(Dir)
While Q.Count
For Each s In GetTopLevelDirs(Q.Dequeue)
Try
dummy = My.Computer.FileSystem.GetDirectoryInfo(s)
D.Add(s)
Q.Enqueue(s)
Catch
' Inaccessible folder
End Try
Next
End While
If Sort AndAlso D.Count Then D.Sort()
Return D
End Function
Friend Function GetTopLevelDirs(ByRef dir As String) As List(Of String)
Try
Return My.Computer.FileSystem.GetDirectories(dir, FileIO.SearchOption.SearchTopLevelOnly).ToList
Catch
Return New List(Of String)
End Try
End Function
Upvotes: 0
Reputation: 414
Use the GetFiles from My.Computer.System and the ReadOnlyCollection(of String) from the system.collections.objectModel import and a searchoption as desired (top or all)
sPath = "C:\debug" ' your desired path
sFile1 = "t*.txt" ' your desired search pattern with * wildcard
sFile2 = "test?.txt" ' your desired search pattern with ? wildcard
dim lstFiles as system.collections.ObjectModel.ReadOnlyCollection(of String) = My.Computer.Filesystem.GetFiles(sPath, FileIO.SearchOption.SearchTopLevelOnly, sFile1)
'lstfiles contains all the files that match your selection
'if you really need an array you can convert the list to array here
dim i as integer = 0
for each sFile as string in lstfiles
a(i)=sfile
i+=1
next
Upvotes: 0
Reputation: 286
This should do it for you. It'll handle wildcards in directory part and filename part
Private Function GetFiles(ByVal Path As String) As List(Of String)
Dim drivePart As String, dirPart As String, filePart As String
drivePart = Path.Substring(0, Path.IndexOf("\") + 1)
dirPart = Path.Substring(Path.IndexOf("\") + 1, Path.LastIndexOf("\") - Path.IndexOf("\") - 1)
filePart = Path.Substring(Path.LastIndexOf("\") + 1)
Dim directories As New List(Of String)
Dim files As New List(Of String)
'' Walk directory tree finding matches
'' This should handle wildcards in any part of the path
Dim currentIndex As Integer = 0
Dim directoryMatch As String() = dirPart.Split("\")
For Each directory As String In directoryMatch
WalkDirectories(drivePart, directories, directoryMatch, currentIndex)
currentIndex += 1
Next
For Each directory As String In directories
files.AddRange(System.IO.Directory.GetFiles(directory, filePart))
Next
Return files
End Function
Private Sub WalkDirectories(ByVal dirPart As String, ByVal directories As List(Of String), ByVal directoryMatch As String(), ByVal currentIndex As Integer)
If currentIndex = directoryMatch.Length Then Return
For Each d As String In System.IO.Directory.GetDirectories(dirPart, directoryMatch(currentIndex))
directories.Add(d)
WalkDirectories(System.IO.Path.Combine(dirPart, d), directories, directoryMatch, currentIndex + 1)
Next
End Sub
Edit: just noticed that it wont handle UNC paths but it should be pretty easy to modify for that if you need to Editted again to handle multiple directory levels and wildcards at multiple levels (eg C:\debug\12*\log1*\errors*.txt
Upvotes: 0
Reputation: 183
I use the following code:
Dim Path As String = "C:\debug"
Dim Dir As New DirectoryInfo(Path)
Dim q = (From x In Dir.GetFiles("*.txt", SearchOption.AllDirectories) Select x.FullName).ToArray
You might need to
Import System.IO
Import System.Linq
Basically your key for the requirement is SearchOption.AllDirectories which iterates through sub directories as well.
Upvotes: 2