Iterate through a directory to get subfolders and certain files - vb.net

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.

Related

How to keep the content of ListBox in Vb.net

If i want to keep the content of a textbox i do this
TextBox1.Text = TextBox1.Text & Something
Is there a way to do the same thing for the content of Items of a Listbox?
In my RichTextBox3 i have the list of files in the C:\Work directory
I Tried this code but it's giving me The content of the last line (It's not adding the lines before)
Do Until number = RichTextBox3.Lines.Length
Dim directory = "C:\Work\" & RichTextBox3.Lines(number)
Dim files() As System.IO.FileInfo
Dim dirinfo As New System.IO.DirectoryInfo(directory)
files = dirinfo.GetFiles("*", IO.SearchOption.AllDirectories)
For Each file In files
ListBox1.Items.Add(file)
Next
number = number + 1
Loop
Help is appreciated
Thanks to all of you
I'm not sure that this will address your stated problem but there's a serious issue with that code and I need to provide a long code snippet to address it and that won't be readable in a comment.
The Lines property of a TextBox or RichTextBox is not "live" data, i.e. it doesn't refer to an array stored within the object. Each time you get the property, a new array is created. You are getting RichTextBox3.Lines twice for every iteration of that loop, so that's obviously wrong. You also should not be adding items to the ListBox one by one like that. You should be creating a list of all the items first, then adding them all with a single call to AddRange:
Dim files As New List(Of FileInfo)
For Each line In RichTextBox3.Lines
Dim folderPath = Path.Combine("C:\Work", line)
Dim folder As New DirectoryInfo(folderPath)
files.AddRange(folder.GetFiles("*", SearchOption.AllDirectories))
Next
ListBox1.Items.AddRange(files.ToArray())
If that code doesn't work as expected, you can debug it and view the contents of files at various stages to make sure that you are getting the files you expect. It might also be worth testing folder.Exists before calling GetFiles, unless you're absolutely sure that each line in the RichTextBox represents an existing folder.
This will do what you want.
number = 0
ListBox1.items.clear()
Do Until number = RichTextBox3.Lines.Length
Dim directory = "C:\Work\" & RichTextBox3.Lines(number)
Dim files() As System.IO.FileInfo
Dim dirinfo As New System.IO.DirectoryInfo(directory)
files = dirinfo.GetFiles("*", IO.SearchOption.AllDirectories)
For Each file In files
ListBox1.Items.Add(file)
Next
number = number + 1
Loop

How to compress multiple files and split the zip while compressing

Hello so I have searched for this a long time allready and havent found anything about this. I search all the folders in the given folder and create an entry in the ziparchive for each file. It is needed that i keep the fodler structure. This is what i have come up with for now.
Imports System.IO
Imports System.IO.Compression
'a list of folders I want to zip. These are all located in the testfolder.
Public Shared ListofBackupFolders As New List(Of String) From {"SDK", "Programms", "Application", "Office", "Reports", "UserSettings", "de", "Intrastat", "XSD"}
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim d As New DirectoryInfo("c:\temp\testfolder")
Dim directories = d.GetDirectories("*")
File.Create("C:\temp\test.zip").Close()
For Each directory In directories
'Only searches the Folders I selecten in the list
If ListofBackupFolders.Contains(directory.Name) Then
SearchFolder(directory.FullName)
End If
Next
End Sub
Private Sub SearchFolder(path As String)
Dim dirInfo As New DirectoryInfo(path)
Dim subDirectories = dirInfo.GetDirectories("*")
If path.EndsWith("Application") Then
'>>> Some of the selected folders are in the Application folder
For Each subdirectory In subDirectories
If ListofBackupFolders.Contains(subdirectory.Name) Then
'recursion to get all the folders in the selected folder
SearchFolder(subdirectory.FullName)
End If
Next
Else
If subDirectories.Any Then
For Each subdirectory In subDirectories
'>>> recursion to get all the folders in the selected folder
SearchFolder(subdirectory.FullName)
Next
End If
End If
Dim files = dirInfo.GetFiles("*")
Using zipToOpen As FileStream = New FileStream("C:\temp\test.zip", FileMode.Open)
Using archive As ZipArchive = New ZipArchive(zipToOpen, ZipArchiveMode.Update)
Dim readmeEntry As ZipArchiveEntry
For Each file In files
'for every File in the folders it creates the path in the zip
Dim zipPath = file.FullName.Replace("C:\", "").Replace("\", "/")
readmeEntry = archive.CreateEntryFromFile(file.FullName, zipPath, CompressionLevel.Fastest)
Next
If Not subDirectories.Any AndAlso Not files.Any Then
'if there are no files in a folder i still want the folder in the zip
Dim folderPath = path.Replace("C:\", "").Replace("\", "/") & "/"
readmeEntry = archive.CreateEntry(folderPath)
End If
End Using
End Using
End Sub
Now the problem I have is that i havent found a way to split the zip after a given volume (example 200mb).
And a other thing I need is that i have a single file that is for example 2gb i have to split that one aswell. This is seperate from the other code.

Get count of similar files in a folder

I have a file, lets call it "myFile.txt", in a folder. There are also going to be other files named "myFile1.txt, myFile2.txt, myFile3.txt, myFile4.txt" in that same folder and so forth. I want to check that folder and count how many times "myFile" shows up in that folder no matter what the extension or the number after "myFile". Here's what I have so far, but it's not getting what I want:
Dim MyFiles1() As String = IO.Directory.GetFiles("filepath", "myFile.txt")
I whipped this up and tested it in Visual Studio:
'Get a list of files from a directory you designate
Dim counter As System.Collections.ObjectModel.ReadOnlyCollection(Of String)
counter = My.Computer.FileSystem.GetFiles("C:\YOURDIR")
'Declare your file name
Dim myfile As String = "YOURFILE"
'Create count dim
Dim Occurrences As Integer = 0
'Check all files in the array and check them against our filename
For Each File As String In counter
If File.Contains(myfile) Then
'If a file is found, add +1
Occurrences = Occurrences + 1
End If
Next
'Display total count
MsgBox("number of files is " & Occurrences)
This will go and search the path you designate. It will check all files like your filename in the dir. If it finds one, it will count it. This also checks for case insensitive names as well so you can get all variants of your file name.
Something like below:
Public Shared Sub ProcessDirectory(ByVal targetDirectory As String)
Dim fileEntries As String() = Directory.GetFiles(targetDirectory)
' Process the list of files found in the directory.
Dim fileName As String
For Each fileName In fileEntries
' do a simple if statement to see if the file name contains "myFile"
' if so add to some count variable you declare
See here for more reference material on the GetFiles() method (which is the key to solving your issue): https://msdn.microsoft.com/en-us/library/07wt70x2%28v=vs.110%29.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1

Copying a list of modified files from multiple source directories to equivalent destination directory

I am learning VB.NET and writing a utility to copy only the modified files from a preset selection of folders to their equivalent in a backup directory.
For example: D:\Profiles\Mail to E:\Backup\Profiles\Mail
I can already do the copy simply with the following:
For Each item In MAILp
My.Computer.FileSystem.CopyDirectory(MAILp, MAILd, True)
Next
But the idea is count the amount of modified files to be copied, and display this all through a progress bar and the background worker (eventually)
At the moment i am working with this;
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Contants for whole activity
Dim lstFiles As New List(Of FileInfo)
Dim fsInfo As FileSystemInfo
'Constants for dirInfo's
Dim dirInfoMAILp As New DirectoryInfo(MAILp)
Dim dirInfoDESKTOPp As New DirectoryInfo(DESKTOPp)
'Loop for Mail
For Each fsInfo In dirInfoMAILp.GetFileSystemInfos
Dim strDestFileName As String = Path.Combine(MAILd, fsInfo.Name)
Dim destFileInfo As New FileInfo(strDestFileName)
If fsInfo.LastWriteTime > destFileInfo.LastWriteTime Then
lstFiles.Add(fsInfo)
End If
Next
'Loop for Desktop
For Each fsInfo In dirInfoDESKTOPp.GetFileSystemInfos
Dim strDestFileName As String = Path.Combine(DESKTOPd, fsInfo.Name)
Dim destFileInfo As New FileInfo(strDestFileName)
If fsInfo.LastWriteTime > destFileInfo.LastWriteTime Then
lstFiles.Add(fsInfo)
End If
Next
'Number of files to copy
Label1.Text = lstFiles.Count
For Each file As FileInfo In lstFiles
System.IO.File.Copy(file.FullName, DESTINATIONMAIN + file.Name, True)
Next
End Sub
My problem is in three parts:
1. If the files do not already exist in the destination, it will throw and exception. This is not good if the utility is being used for the first time. How can I use an ELSE in the loop to copy the file if it doesn't exist in the destination?
2. The copy does not copy folders, only files, can I expand it to include folders? Ideally the differential check loop targets the Top folder then goes through every sub folder and file, adding it to the list.
3. When copied to the destination folder, the files are copied to the destination top folder "E:\Backup\Profiles", rather than in the sub-folders they were copied from.
Can anyone point me in the right direction?

How to read files in folders?

I am trying to get my application to check for folders in the folderbrowserdialogs selectedpath and then get those files, but it doesn't work I have tried both listed ways below. The second way gives me an error: (Expression is of type char which is not a collection type)
For Each folder In FileBrowserDialog.SelectedPath
Dim counter As _
System.Collections.ObjectModel.ReadOnlyCollection(Of String)
counter = My.Computer.FileSystem.GetFiles(folder)
Label1.Text = counter.Count.ToString
Next
For Each folder In FileBrowserDialog.SelectedPath
Dim counter As _
System.Collections.ObjectModel.ReadOnlyCollection(Of String)
For Each foundfile In folder
counter = My.Computer.FileSystem.GetFiles(foundfile)
Label1.Text = counter.Count.ToString
Next
Any help is appreciated.
FolderBrowserDialog1.SelectedPath will return the path the user selected in the dialog. You still need to write code to go get the files. There may not be a need to get the folders and then files in them. Net has ways to do that for you:
FolderBrowserDialog1.ShowDialog()
Dim myPath As String = FolderBrowserDialog1.SelectedPath
' get all files for a folder
Dim files = Directory.GetFiles(myPath)
' get all files for all sub folders
Dim files = Directory.GetFiles(myPath, "*.*",
System.IO.SearchOption.AllDirectories)
' get certain file types for folder and subs
Dim files = Directory.GetFiles(myPath, "*.jpg",
System.IO.SearchOption.AllDirectories)
You also are not going to be able to simply assign the results to a ReadOnlyCollection like that, because they are ReadOnly. The collection needs to be created/instanced with the complete list:
Dim counter As new ReadOnlyCollection(Of String)(files)