What is the fastest way to retrieve all the files within a directory (including sub folders). Currently I am using this function:
Public Function FindFiles(path As String, Recursive As Boolean) As Boolean
Dim dirInfo As New IO.DirectoryInfo(path)
Dim fileObject As FileSystemInfo
If Recursive = True Then
For Each fileObject In dirInfo.GetFileSystemInfos()
If System.IO.Directory.Exists(fileObject.FullName) Then
FindFiles(fileObject.FullName, Recursive)
Else
'fileObject.FullName - found file
End If
Next
Else
For Each fileObject In dirInfo.GetFileSystemInfos()
If Not System.IO.Directory.Exists(fileObject.FullName) Then
'fileObject.FullName - found file
End If
Next
End If
End Function
Thanks
try this
Private Function getAllFolders(ByVal directory As String) As String()
Dim fi As New IO.DirectoryInfo(directory) 'Create object
Dim path() As String = {} 'Array to store paths
'Loop through subfolders
For Each subfolder As IO.DirectoryInfo In fi.GetDirectories()
Array.Resize(path, path.Length + 1) 'Add this folders name
path(path.Length - 1) = subfolder.FullName
'Recall function with each subdirectory
For Each s As String In getAllFolders(subfolder.FullName)
Array.Resize(path, path.Length + 1)
path(path.Length - 1) = s
Next
Next
Return path
End Function
Related
i am working on vb.net desktop application.now i need that files coming from directory is in with extension .txt and .sql and also need that files coming in order by folder name. in need both together how to do it?
Try
Dim s As String = Txtfolder.Text
Dim files As List(Of String) = New List(Of String)()
Try
For Each f As String In Directory.GetFiles(s, "*.*").Where(Function(f1) f1.EndsWith(".sql") OrElse f1.EndsWith(".txt")).OrderBy(Function(f) f.LastWriteTime).First()
files.Add(f)
Next
For Each d As String In Directory.GetDirectories(s)
files.AddRange(DirSearch(d))
Next
Catch excpt As System.Exception
MessageBox.Show(excpt.Message)
End Try
Private Function DirSearch(ByVal sDir As String) As List(Of String)
Dim files As List(Of String) = New List(Of String)()
Try
For Each f As String In Directory.GetFiles(sDir, "*.*").Where(Function(f1) f1.EndsWith(".sql") OrElse f1.EndsWith(".txt"))
files.Add(f)
Next
For Each d As String In Directory.GetDirectories(sDir)
files.AddRange(DirSearch(d))
Next
Catch excpt As System.Exception
MessageBox.Show(excpt.Message)
End Try
Return files
End Function
Here is an example of option 1 from my comment, i.e. get all file paths and filter yourself:
Dim folderPath = "folder path here"
Dim filePaths = Directory.GetFiles(folderPath).
Where(Function(s) {".txt", ".sql"}.Contains(Path.GetExtension(s))).
OrderBy(Function(s) Path.GetFileName(s)).
ToArray()
Here's an example of option 2, i.e. get paths by extension and combine:
Dim folderPath = "folder path here"
Dim filePaths = Directory.GetFiles(folderPath, "*.txt").
Concat(Directory.GetFiles(folderPath, "*.sql")).
OrderBy(Function(s) Path.GetFileName(s)).
ToArray()
An alternative method, which allows searching for multiple directories and filtering the results using multiple search patterns.
It returns an ordered List(Of String):
Private Function DirSearch(ByVal sDirList As String(), SearchPatter As String()) As List(Of String)
Return sDirList.SelectMany(
Function(dir) SearchPatter.SelectMany(
Function(filter)
Return Directory.GetFiles(dir, filter, SearchOption.AllDirectories)
End Function).OrderBy(Function(xDir) xDir)).ToList()
End Function
You can pass the method a list of paths and a list of extensions:
Dim SearchPaths As String() = New String() {"[Directory1]", "[Directory2]"}
Dim ItemSearchPattern As String() = New String() {"*.txt", "*.sql", "*.jpg"}
Dim DirListing As List(Of String) = DirSearch(SearchPaths, ItemSearchPattern)
Extract the content of a sigle directory with:
Dim FilesInDir As List(Of String) = DirListing.
Where(Function(entry) entry.ToUpper().
Contains("[DirectoryName]".ToUpper())).ToList()
This is a case insensitive filter. Remove (ToUpper()) for a case sensitive one.
I would need to make an array list, displaying all folders that are in the 3rd subfolder from the current one.
Folder1/sub1folder/sub2folder/sub3folder
It has to be recursive. what I need is an array of strings that contains all the strings like above.
I do know how to look recursively into folders, but I do not know how to limit the search to the 3rd subfolder.
Thanks!
Here's my stab at it. I tested it and it works for me:
Dim resultList as List(Of String) = DirectorySearch(baseDirectoryPath, 0)
Function DirectorySearch(directoryPath As String, level As Integer) As List(Of String)
level += 1
Dim directories As String() = IO.Directory.GetDirectories(directoryPath)
Dim resultList As New List(Of String)
If level = 3 Then
For Each subDirectoryPath In directories
Dim result As String = GetFinalResult(subDirectoryPath)
resultList.Add(result)
Next
Else
For Each subDirectoryPath In directories
Dim partialResultList As List(Of String) = DirectorySearch(subDirectoryPath, level)
resultList.AddRange(partialResultList)
Next
End If
Return resultList
End Function
Private Function GetFinalResult(directoryPath As String) As String
Dim directoryInfo As New IO.DirectoryInfo(directoryPath)
Return String.Format("{0}/{1}/{2}/{3}",
directoryInfo.Parent.Parent.Parent.Name,
directoryInfo.Parent.Parent.Name,
directoryInfo.Parent.Name,
directoryInfo.Name)
End Function
If you had a recursive function which began at the current folder:
Public Function recurse(Optional depth As Integer = 0) As String()
Dim folderList As String()
If (depth < 3) Then
depth += 1
folderList = recurse(depth)
Else
'Do third subfolder analysis and set the output to folderList
Return folderList
End If
End Sub
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?
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.
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
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
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
I am getting an exception when running the following code.
Public Function getSongs() As Song()
' Dim dir As New DirectoryInfo(Application.ExecutablePath)
Dim dir As New DirectoryInfo(directory)
Dim songsInDir() As Song = Nothing
Dim i As Integer = 0
For Each file As FileInfo In dir.GetFiles()
'only read ".mp3" files
If file.Extension = ".mp3" Then
songsInDir(i) = New Song(file.Name)
i = +i
End If
Next
Return songsInDir
End Function
I get an error on line:
songsInDir(i) = New Song(file.Name)
I get an uncaught exception that says:
"Object reference not set to an instance of an object."
The song object has a:
Public Sub new(By Val filename as String)
... sub that sets a variable and retrieves file info (this code works)
Any help would be appreciated!
Try using a list:
Public Function getSongs() As Song()
Dim dir As New DirectoryInfo(directory)
Dim songsInDir() As New List(of Song)
For Each file As FileInfo In dir.GetFiles()
'only read ".mp3" files
If file.Extension = ".mp3" Then
songsInDir.Add(New Song(file.Name)
End If
Next
Return songsInDir.ToArray()
End Function
Your problem is that arrays need a size when they're initialized and setting it to Nothing gives you exactly that. Give the array a size and don't set it to Nothing. Also, there's a much cleaner way to do this.
Public Function getSongs() As Song()
Dim songFiles As String() = Directory.GetFiles(directory, "*.mp3")
Dim songsInDir(songFiles.Length) As Song
Dim i As Integer = 0
For Each file As String In songFiles
songsInDir(i) = New Song(Path.GetFileName(file))
i = +i
Next
Return songsInDir
End Function
You should specify the array size
Dim i as Integer = dir.GetFiles().count or dir.FilesCount()
Dim songsInDir(i) As Song = Nothing
or you can use dynamic array
put this line inside your for loop
ReDim Preserve songsInDir(i)
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 5 years ago.
Hi all i have been trying to search a specified directory and all sub directories for all files that have the specified file extension. However the inbuilt command is useless as it errors up and dies if you dont have access to a directory. So here's what i have at the moment:
Private Function dirSearch(ByVal path As String, Optional ByVal searchpattern As String = ".exe") As String()
Dim di As New DirectoryInfo(path)
Dim fi As FileInfo
Dim filelist() As String
Dim i As Integer = 0
For Each fi In di.GetFiles
If System.IO.Path.GetExtension(fi.FullName).ToLower = searchpattern Then
filelist(i) = fi.FullName
i += 1
End If
Next
Return filelist
End Function
However i get an "System.NullReferenceException: Object reference not set to an instance of an object." when i try to access the data stored inside the filelist string array.
Any idea's on what im doing wrong?
You didn't instantiate the Dim filelist() As String array. Try di.GetFiles(searchPattern)
Dim files() as FileInfo = di.GetFiles(searchPattern)
Use static method Directory.GetFiles that returns an array string
Dim files = Directory.GetFiles(Path,searchPattern,searchOption)
Demo:
Dim files() As String
files = Directory.GetFiles(path, "*.exe", SearchOption.TopDirectoryOnly)
For Each FileName As String In files
Console.WriteLine(FileName)
Next
Recursive directory traversal:
Sub Main()
Dim path = "c:\jam"
Dim fileList As New List(Of String)
GetAllAccessibleFiles(path, fileList)
'Convert List<T> to string array if you want
Dim files As String() = fileList.ToArray
For Each s As String In fileList
Console.WriteLine(s)
Next
End Sub
Sub GetAllAccessibleFiles(path As String, filelist As List(Of String))
For Each file As String In Directory.GetFiles(path, "*.*")
filelist.Add(file)
Next
For Each dir As String In Directory.GetDirectories(path)
Try
GetAllAccessibleFiles(dir, filelist)
Catch ex As Exception
End Try
Next
End Sub
Use System.IO.Directory.EnumerateFiles method and pass SearchOption.AllDirectories in to traverse the tree using a specific search pattern. Here is an example:
foreach (var e in Directory.EnumerateFiles("C:\\windows", "*.dll", SearchOption.AllDirectories))
{
Console.WriteLine(e);
}