I'm trying to create a list of all directories and their sub-directories in a given path in visual studio 2012.
It's a very long time since I've been in touch with visual basic. I hope somebody can show a simple way for this task.
Any kind of help is much appreciated. :)
In the System.IO namespace
Directory.GetDirectories(string, string, SearchOptions)
A good example from MSDN
Dim dirs As String() = Directory.GetDirectories("c:\", "*.*", SearchOption.AllDirectories)
Console.WriteLine("The number of directories starting with p is {0}.", dirs.Length)
Dim dir As String
For Each dir In dirs
Console.WriteLine(dir)
Next
Catch e As Exception
Console.WriteLine("The process failed: {0}", e.ToString())
End Try
However keep in mind that some directories could have particular access permissions and your code could fail with an IOException. (That's particularly true for the system directories)
Another option is through the use of Directory.EnumerateDirectories that is preferable when you work with many directories and you don't need to have the string array with names filled.
EnumerateDirectories start immediately without waiting to filling the array and is very useful in situation where your code loops over the enumeration
For Each dirName in Directory.EnumerateDirectories("C:\", "p*", SearchOptions.AllDirectories)
..... do something with the directory here ....
Next
Dim path as string ="c:\DirectoryTest"
Dim result = Directory.EnumerateDirectories(path, "*", System.IO.SearchOption.AllDirectories)
This recursive method will get all directories & its sub-directories from a given path:
Option 1#
Public Shared Sub ProcessDirectory(ByVal targetDirectory As String)
Dim subdirectoryEntries As String() =
Directory.GetDirectories(targetDirectory)
' Recurse into subdirectories of this directory.
Dim subdirectory As String
For Each subdirectory In subdirectoryEntries
ProcessDirectory(subdirectory)
Next subdirectory
End Sub
Option 2#
Module Module1
Sub Main()
Try
Dim dirPath As String = "c:\\myDirctory"
Dim dirs As List(Of String) = New List(Of String)(Directory.EnumerateDirectories(dirPath))
For Each folder In dirs
Console.WriteLine("{0}", folder.Substring(folder.LastIndexOf("\") + 1))
Next
Console.WriteLine("{0} directories found.", dirs.Count)
Catch UAEx As UnauthorizedAccessException
Console.WriteLine(UAEx.Message)
Catch PathEx As PathTooLongException
Console.WriteLine(PathEx.Message)
End Try
End Sub
End Module
You can refer MSDN for further details:
http://msdn.microsoft.com/en-us/library/c1sez4sc.aspx
http://msdn.microsoft.com/en-us/library/dd383304.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
Related
I am working on a program that will move files to a database, text files to be exact. The user will have a starting directory and inside will multiple sub folders and files and so on. I want to go through each Folder and sub folder looking for the text files and add them accordingly to the database so it resembles a directory structure in a way. In the program the files are organized such as the folders are "Categories" that are displayed into a tree view.I am only adding the folder names(as Categories) that do contain text files and their subs and so forth. As well I need to figure out where to plug in the adding of the "Category". As of right now I am using a couple of listboxes for my output until I can get it all figured out.
lstfiles.Items.Add(Dir)
For Each file In System.IO.Directory.GetFiles(Dir)
Dim fi As System.IO.FileInfo = New IO.FileInfo(file)
If fi.Extension = ".txt" Then
If lstRootFolderFiles.Items.Contains(file) = False Then
lstfiles.Items.Add(file)
AddFile(file, Gennumber(9999))
End If
End If
Next
For Each folder In System.IO.Directory.GetDirectories(Dir)
lstfiles.Items.Add(folder)
For Each file In System.IO.Directory.GetFiles(folder)
Dim fi As System.IO.FileInfo = New IO.FileInfo(file)
If fi.Extension = ".txt" Then
If lstRootFolderFiles.Items.Contains(file) = False Then
lstfiles.Items.Add(file)
End If
End If
Next
Next
I have gotten so far as to iterate through the directory and get files but it returns folders that are empty. And I need to figure out where I need to put in my addcategory function. And also remember the last one that was added so they can be added as a subcategory.
I think I am making a big mess of it all, or over thinking the whole thing.
Any assistance or guidance would be appreciated.Thank you
The end result that I came up with was much different from my original posting, as it was my way of thinking of how it was going to work. I split up the two main functions. Retrieving the Folders and retrieving the files.
DirEx is the Import Directory, CatID is the Tag of the selected Treenode where the folders are going to added in.
Private Sub DirImport_GetSubDirectories(ByVal DirEx As String, ByVal CatID As Integer)
Try
Dim ClsData As New clsNoteData
'Set the DatabaseFile Property of the class
ClsData.Database = LoadedLibraryDatabase
' Get all subdirectories
Dim subdirectoryEntries() As String = Directory.GetDirectories(DirEx)
' Loop through them to see if they have any other subdirectories
Dim subdirectory As String
For Each subdirectory In subdirectoryEntries
'If the Directory is not Empty
If Not Directory.GetFileSystemEntries(subdirectory).Length = 0 Then
Dim di As DirectoryInfo = New DirectoryInfo(subdirectory)
'Creating Random Number
Dim NewCatID As Integer = GenNumber(9999)
'Call for a new Sub Category
ClsData.NewSubCategoryNode(LoadedLibraryDatabase, NewCatID, CatID, di.Name, -1)
'Get files in the current Directory
DirImport_GetFiles(subdirectory, NewCatID)
'Get the next set of Subfolders
DirImport_GetSubDirectories(subdirectory, NewCatID)
End If
Next
Catch ex As Exception
End Try
End Sub
Private Sub DirImport_GetFiles(ByVal DirEx As String, ByVal CatID As Integer)
Dim Files() As String = Directory.GetFiles(DirEx, "*.txt")
Dim file As String
For Each file In Files
Dim clsNoteData As New clsNoteData
Dim fi As FileInfo = New FileInfo(file)
clsNoteData.Database = LoadedLibraryDatabase
clsNoteData.NewNote_ID = GenNumber(99999)
clsNoteData.NewNote_CatID = CatID
clsNoteData.NewNote_Title = Path.GetFileNameWithoutExtension(file)
clsNoteData.NewNote(False, file)
Next
End sub
So here it is for anyone who may want to do something similar.
i'm trying to create a simple anti-cheat which detects external cheats in all the C drive, but i don't know how to check if a determinate file exists in all the C drive, any help?
Here is code that I adapted from How to: Iterate Through a Directory Tree. In the example, the FileExists() function returns True if the file bit32.txt is found anywhere on the C drive. Not all files and directories may be accessible. In that case, the function display the paths of these files and directories. You may want to adapt the code to do whatever you want in these cases.
Imports System.IO
Module Module1
Private Sub Main(ByVal args() As String)
Dim exists As Boolean = FileExists(New DriveInfo("C").RootDirectory, "bit32.txt")
End Sub
Private Function FileExists(ByVal root As DirectoryInfo, ByVal filename As String) As Boolean
Dim files() As FileInfo = Nothing
Dim subDirs() As DirectoryInfo = Nothing
' First, process all the files directly under this folder
Try
files = root.GetFiles("*.*")
Catch e As Exception
' This code just writes out the message and continues to recurse.
' You may decide to do something different here. For example, you
' can try to elevate your privileges and access the file again.
Console.WriteLine(e.Message)
End Try
If (Not (files) Is Nothing) Then
For Each fi As FileInfo In files
' In this example, we only access the existing FileInfo object. If we
' want to open, delete or modify the file, then
' a try-catch block is required here to handle the case
' where the file has been deleted since the call to TraverseTree().
'Console.WriteLine(fi.FullName);
If (fi.Name = filename) Then
Return True
End If
Next
End If
Try
' Now find all the subdirectories under this directory.
subDirs = root.GetDirectories
For Each dirInfo As DirectoryInfo In subDirs
' Resursive call for each subdirectory.
If FileExists(dirInfo, filename) Then
Return True
End If
Next
Catch e As Exception
' This code just writes out the message and continues to recurse.
' You may decide to do something different here. For example, you
' can try to elevate your privileges and access the file again.
Console.WriteLine(e.Message)
End Try
Return False
End Function
End Module
You can have an extension on DirectoryInfo that non-recursively iterates through the root directory looking for files.
<Extension()>
Public Iterator Function GetFilesDepthFirst(ByVal root As DirectoryInfo, ByVal Optional dirPattern As String = "*", ByVal Optional filePattern As String = "*.*") As IEnumerable(Of FileInfo)
Dim stack = New Stack(Of DirectoryInfo)()
stack.Push(root)
While stack.Count > 0
Dim current = stack.Pop()
Dim files = Enumerable.Empty(Of FileInfo)()
Dim dirs = Enumerable.Empty(Of DirectoryInfo)()
Try
dirs = current.EnumerateDirectories(searchPattern:=dirPattern)
files = current.EnumerateFiles(searchPattern:=filePattern)
Catch ex1 As UnauthorizedAccessException
Catch ex2 As PathTooLongException
End Try
For Each file As FileInfo In files
Yield file
Next
For Each dir As DirectoryInfo In dirs
stack.Push(dir)
Next
End While
End Function
You could then call it fairly easily like this:
Dim dInfo = New DirectoryInfo("C:\")
Dim matches = dInfo.GetFilesDepthFirst(filePattern:="somefile.dll")
Dim exists = matches.Any()
Also, the more specific you are at the starting directory, the quicker it will run. Usually searching from the root of C:\ is a very slow and bad idea.
I tried to practise, search and i didn't find a solution to how to rename all the folders and sub-folders in a desired folder. For example i want to loop trough all the folders and add "_test" to the end, i searched, practiced and i didn't find any great solution so i'm asking to you if you have any snippet of code, or just and idea. I started with creating an array of all the folders within a folder by doing that:
Dim folderArray() As String = IO.Directory.GetDirectories(TextBoxPath.Text, "*", IO.SearchOption.AllDirectories)
For Each folder In folderArray
Dim infoParent As New IO.DirectoryInfo(folder)
Dim folderParent = infoParent.Parent.FullName
Dim folderName = folder.Split(IO.Path.DirectorySeparatorChar).Last()
FileSystem.Rename(folder, folderParent & "\" & folderName & "_Test")
Next
But that's not working, because i rename the directories, so the array is not valid (folderArray) because it has the old directory path.
If you have a way to do it, i'm opened to suggestions, thanks.
I would try do it recursively to make sure it's done at the bottom-most level first. (might not be 100% correct code, but just to give the general idea)
Sub RenameFolderRecursive(path As String)
For Each f As String In IO.Directory.GetDirectories(path)
RenameFolderRecursive(f)
Next
IO.Directory.Move(path, path & "_test")
End Sub
See if that works.
This sounds like a job for recursion. Since you don't know how many folders any given folder will contain, or how many levels deep a folder structure can be, you can't just loop through it. Instead, write a function which solves a discrete piece of the overall problem and recurse that function. My VB is very rusty so this might not be 100% valid (you'll definitely want to debug it a bit), but the idea is something like this:
Function RenameFolderAndSubFolders(ByVal folder as String)
' Get the sub-folders of the current folder
Dim subFolders() As String = IO.Directory.GetDirectories(folder, "*", IO.SearchOption.AllDirectories)
If subFolders.Length < 1 Then
'This is a leaf node, rename it and return
FileSystem.Rename(folder, folder & "_Test")
Return
End If
' Recurse on all the sub-folders
For Each subFolder in subFolders
RenameFolderAndSubFolders(subFolder)
' Rename the current folder once the recursion is done
FileSystem.Rename(subFolder, subFolder & "_Test")
Next
End Function
The idea here is simple. Given a folder name, get all of the child folders. If there aren't any, rename that folder. If there are, recurse the same function on them. This should find all of the folders and rename them accordingly. To kick off the process, just call the function on the root folder of the directory tree you want renamed.
Sub RenameAll(ByVal sDir As String)
Try
For Each d As String In Directory.GetDirectories(sDir)
IO.Directory.Move(d, d & "_test")
RenameAll(d & "_test")
Next
Catch x As System.Exception
End Try
End Sub
Here is recursive function that might do the job you need.
Private Sub RenameAllFolds(d As String)
Dim subfolds() As String = IO.Directory.GetDirectories(d)
If subfolds.Count = 0 Then
IO.Directory.Move(d, d & "_Test")
Else
For Each dir As String In subfolds
RenameAllFolds(dir)
Next
IO.Directory.Move(d, d & "_Test")
End If
End Sub
Sub Main()
Dim inf As String = "C:\renametest"
Dim folds() As String = IO.Directory.GetDirectories(inf)
For Each f As String In folds
RenameAllFolds(f)
Next
Console.ReadKey()
End Sub
I got a question in Visual Basic 2010: How can I copy all subfolders (only the subfolders, not the main folder) into another folder?
You need to recursively iterate through all the files and folders and copy them. This method should do the job for you:
Public Sub CopyDirectory(ByVal sourcePath As String, ByVal destinationPath As String)
Dim sourceDirectoryInfo As New System.IO.DirectoryInfo(sourcePath)
' If the destination folder don't exist then create it
If Not System.IO.Directory.Exists(destinationPath) Then
System.IO.Directory.CreateDirectory(destinationPath)
End If
Dim fileSystemInfo As System.IO.FileSystemInfo
For Each fileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos
Dim destinationFileName As String =
System.IO.Path.Combine(destinationPath, fileSystemInfo.Name)
' Now check whether its a file or a folder and take action accordingly
If TypeOf fileSystemInfo Is System.IO.FileInfo Then
System.IO.File.Copy(fileSystemInfo.FullName, destinationFileName, True)
Else
' Recursively call the mothod to copy all the neste folders
CopyDirectory(fileSystemInfo.FullName, destinationFileName)
End If
Next
End Sub
System.IO has two classes that you can use in a recursive fashion to do this all from code.
DirectoryInfo
FileInfo
DirectoryInfo has two methods that are relevant:
GetDirectories
GetFiles
FileInfo has a CopyTo method
Given those objects and methods and a bit of creative recursion you should be able to copy the stuff fairly easily.
This seems to be the simplest solution:
For Each oDir In (New DirectoryInfo("C:\Source Folder")).GetDirectories()
My.Computer.FileSystem.CopyDirectory(oDir.FullName, "D:\Destination Folder", overwrite:=True)
Next oDir
1 Line:
My.Computer.FileSystem.CopyDirectory(txtSourceDirectory.Text, txtDestinationDirectory.Text, True)
I am trying to search the C:\ drive for all files with a certain extension. I am using the following code which is working fine, however when it encounters an error the whole process stops rather than continuing with the scan. (running in backgroundworker, hence the invoke)
Private Sub ScanFiles(ByVal rootFolder As String, ByVal fileExtension As String)
'Determine if the current folder contains any sub folders
Dim subFolders() As String = System.IO.Directory.GetDirectories(rootFolder)
For Each subFolder As String In subFolders
ScanFiles(subFolder, fileExtension)
Next
For Each file As String In System.IO.Directory.GetFiles(rootFolder, fileExtension)
lb.BeginInvoke(New AddValue(AddressOf AddItems), file)
Next
End Sub
How can I make this code continue once an error is encountered?
If you don't have access to explore C drive itself then you are out of luck. but if you are getting an exception because you don't have access to some child folder in the tree, you can avoid it by putting your code in an try-catch block.
Private Sub ScanFiles(ByVal rootFolder As String, ByVal fileExtension As String)
'Determine if the current folder contains any sub folders '
try
Dim subFolders() As String = System.IO.Directory.GetDirectories(rootFolder)
For Each subFolder As String In subFolders
ScanFiles(subFolder, fileExtension)
Next
For Each file As String In System.IO.Directory.GetFiles(rootFolder, fileExtension)
lb.BeginInvoke(New AddValue(AddressOf AddItems), file)
Next
catch (Ex As UnauthorizedAccessException)
'Ignore Access Errors '
end try
End Sub