How to read files in folders? - vb.net

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)

Related

Iterate through a directory to get subfolders and certain files

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.

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

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

Comparing files in list of string to files in target directory

I have searched this issue for 2 days, without finding a solution. I might be using the wrong search terms, due to my limited knowledge of the subject.
I have 2 folders, a source and a target, each with files in them. I need to compare the files in these 2 dirs and delete the duplicate files from the target dir before moving the files from the source dir.
I have created a list of string for both dirs. But I can't seem to figure out how to make the dupes in the targetdir to get deleted instead of from the list itself. However, if I put targetdir or sourcedir in the File.Exists() and File.Delete(), it doesn't see the files.
My code is below. Can anyone help me with this?
Dim sourcedir As String
sourcedir = TextBox1.Text + "\"
Dim targetdir As String
targetdir = readValue + "\"
For Each filename In filelist
If System.IO.File.Exists(filename) Then
System.IO.File.Delete(filename)
End If
Next
Edit:
Thank you so very much. This is the code that I used, in case someone else has the same issue.
Dim sourcedir As String
sourcedir = TextBox1.Text + "\"
Dim targetdir As String
targetdir = readValue + "\"
Dim sourceFilePaths = My.Computer.FileSystem.GetFiles(sourcedir, FileIO.SearchOption.SearchAllSubDirectories)
Dim targetFilePaths = My.Computer.FileSystem.GetFiles(targetdir, FileIO.SearchOption.SearchAllSubDirectories)
'Compare only file names, ignoring paths, and get a list of duplicates.
Dim duplicateFileNames = sourceFilePaths.Select(Function(filePath) System.IO.Path.GetFileName(filePath)).
Intersect(targetFilePaths.Select(Function(filePath) System.IO.Path.GetFileName(filePath)))
'Combine target folder path with duplciate file names and delete each one.
For Each filePath In duplicateFileNames.Select(Function(fileName) System.IO.Path.Combine(targetdir, fileName))
System.IO.File.Delete(filePath)
Application.DoEvents()
Next
E.g.
Dim sourceFolderPath = "C:\SourceFolder"
Dim targetFolderPath = "C:\TargetFolder"
Dim sourceFilePaths = Directory.GetFiles(sourceFolderPath)
Dim targetFilePaths = Directory.GetFiles(targetFolderPath)
'Compare only file names, ignoring paths, and get a list of duplicates.
Dim duplicateFileNames = sourceFilePaths.Select(Function(filePath) Path.GetFileName(filePath)).
Intersect(targetFilePaths.Select(Function(filePath) Path.GetFileName(filePath)))
'Combine target folder path with duplciate file names and delete each one.
For Each filePath In duplicateFileNames.Select(Function(fileName) Path.Combine(targetFolderPath, fileName))
File.Delete(filePath)
Next
Here's an option that doesn't use LINQ:
Dim sourceFolderPath = "C:\SourceFolder"
Dim targetFolderPath = "C:\TargetFolder"
Dim sourceFilePaths = Directory.GetFiles(sourceFolderPath)
Dim targetFilePaths = Directory.GetFiles(targetFolderPath)
Dim sourceFileNames As New List(Of String)
For Each sourceFilePath In sourceFilePaths
sourceFileNames.Add(Path.GetFileName(sourceFilePath))
Next
For Each targetFilePath In targetFilePaths
Dim targetFileName = Path.GetFileName(targetFilePath)
If sourceFileNames.Contains(targetFileName) Then
File.Delete(targetFilePath)
End If
Next
It's important to note that both these examples are case-sensitive. Both the Intersect and Contains methods will accept an IEqualityComparer(Of String) though, so you can provide one to make them case-insensitive.

File Icons and List view

How to retrieve file icons associated with the file types and add them with the items of Listview in vb.net
I read about SHGetFileInfo but I didn't understand anything from that
please give me solution or please explain me ho system works with the .net controls in details
Having looked up SHGetFileInfo I can see why you're confused by it, but I think it might be slightly overkill for what I think you're trying to do i.e. enumerating the contents of a folder and adding items to the Listview.
If we have a form that contains a ListView and an ImageList, with the two related by having the ListView's LargeImageList property set to the ImageList, then here's how we put the contents of a folder into the ListView with the icons coming from the associated EXE file for each file.
Imports System.IO
Imports System.Drawing
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim dirInfo As DirectoryInfo
Dim fileInfo As FileInfo
Dim exePath As String
Dim exeIcon As Icon
dirInfo = New DirectoryInfo(path_to_some_folder
'We use this For...Each to iterate over the collection of files in the folder
For Each fileInfo In dirInfo.GetFiles
'We can only find associated exes by extension, so don't show any files that have no extension
If fileInfo.Extension = String.Empty Then
Else
'Use the function to get the path to the executable for the file
exePath = GetAssociatedProgram(fileInfo.Extension)
'Use ExtractAssociatedIcon to get an icon from the path
exeIcon = Drawing.Icon.ExtractAssociatedIcon(exePath)
'Add the icon if we haven't got it already, with the executable path as the key
If ImageList1.Images.ContainsKey(exePath) Then
Else
ImageList1.Images.Add(exePath, exeIcon)
End If
'Add the file to the ListView, with the executable path as the key to the ImageList's image
ListView1.Items.Add(fileInfo.Name, exePath)
End If
Next
End Sub
GetAssociatedProgram comes from developer.com
Public Function GetAssociatedProgram(ByVal FileExtension As _
String) As String
' Returns the application associated with the specified
' FileExtension
' ie, path\denenv.exe for "VB" files
Dim objExtReg As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.ClassesRoot
Dim objAppReg As Microsoft.Win32.RegistryKey = _
Microsoft.Win32.Registry.ClassesRoot
Dim strExtValue As String
Try
' Add trailing period if doesn't exist
If FileExtension.Substring(0, 1) <> "." Then _
FileExtension = "." & FileExtension
' Open registry areas containing launching app details
objExtReg = objExtReg.OpenSubKey(FileExtension.Trim)
strExtValue = objExtReg.GetValue("").ToString
objAppReg = objAppReg.OpenSubKey(strExtValue & _
"\shell\open\command")
' Parse out, tidy up and return result
Dim SplitArray() As String
SplitArray = Split(objAppReg.GetValue(Nothing).ToString, """")
If SplitArray(0).Trim.Length > 0 Then
Return SplitArray(0).Replace("%1", "")
Else
Return SplitArray(1).Replace("%1", "")
End If
Catch
Return ""
End Try
End Function
At the end of all of that, when you run this code on this folder:
alt text http://www.philippursglove.com/stackoverflow/listview1.png
you should get:
alt text http://www.philippursglove.com/stackoverflow/listview2.png
If you know the file name of the file whose icon you want, you can use the System.Drawing.Icon.ExtractAssociatedIcon function for that purpose. e.g.
Icon ico = System.Drawing.Icon.ExtractAssociatedIcon(#"C:\WINDOWS\system32\notepad.exe");
You can also refer to my answer to a related question for more implementation details.