Am learning arrays at the moment and I have the below piece of code that goes through drive C: and displays the files in in a list box.
I want to try and expand it to use array.sort so that it gets the files, puts them into an array, and then I can sort by filename or file size. I have been rattling my brain over this - as to how do I put the files into an array.
Would like an explanation if possible as more interested in learning it rather than the answer.
Thanks!
Private Sub btnclick_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnclick.Click
Call Clearlist()
Dim strFilesinfo As System.IO.FileInfo
Dim strlength As Double = 0
Dim strname As String = ""
For Each strFiles As String In My.Computer.FileSystem.GetFiles("c:\")
strFilesinfo = My.Computer.FileSystem.GetFileInfo(strFiles)
strlength = strFilesinfo.Length
strname = strFilesinfo.Name
lstData.Items.Add(strname & " " & strlength.ToString("N0"))
Next
End Sub
End Class
To allow the data to be sortable, you'd need to be displaying something that could treat that information separately (i.e. a class or structure). You might also find that a different type of control, such as a DataGridView might be easier to get to grips with.
The .Net framework does define an interface, IBindingList which collections can implement to show that they report, amongst other things, sorting.
I'm providing this as a sample for learning purposes but it should not be used as-is. Getting every file from the entire C:\ should not be done like this. Aside from the performance issues there are windows security limitations that won't actually let you do this.
The FileList being populated here is getting just the TopDirectoryOnly. If you change that input to "AllDirectories" it will get all the subdirectories but it will fail as I stated before.
Dim path As String = "C:\"
Dim dir As New System.IO.DirectoryInfo(path)
Dim fileList = dir.GetFiles("*.*", IO.SearchOption.TopDirectoryOnly)
Dim fileSort = (From file In fileList _
Order By file.Name _
Select file.Name, file.Length).ToList
For Each file In fileSort
With file
lstData.Items.Add(String.Format("{0} {1}", .Name, .Length.ToString("N0")))
End With
Next file
Just change the Order By in the LINQ query to change how the sorting is done. There are many other ways to do the sorting but LINQ will handle it for you with very little code.
Related
I have a WinForms project that contains a RichTextBox (RTB) written with VB
I have set ShortcutsEnabled = FALSE in the RTB
To use any Spell Checker I am guessing this would need to set to TRUE
That is NOT my question! I have been reading for way more hours than I care to admit
With the understanding that Spell Checking is easy if you have a ASP.Net OR WPF project
Well I don't so here are the three candidates from NuGet NONE of these candidates offer much help
WeCantSpell.Hunspell and VPKSoft.SpellCheckUtility and NetSpell
I am not asking for a recommendation
Because I can not find a tutorial and am clueless on how to implement these Add In's with code
As well as NOT knowing if they are compatible with WinForms
I even looked at this CP post
CP LINK
Just a suggestion how to use one of these Add In's OR how to add spell checking to the RTB?
To achieve spell checking, you can try Nuget Package NHunspell.
First, you need to add "NHunspell" from "NuGet" and import it. The specific operation is as follows:
Right click the Reference and select "Manage NuGet Packages...", then type "NHunspell " in the search bar and install it:
Second step, you need to create a folder to store ".aff" and ".dic" like this.
Download the "zip" containing the corresponding file, you can access this site.
Here is a demo you can refer to.
Private Sub btCheck_Click(sender As Object, e As EventArgs) Handles btCheck.Click
Dim affFile As String = AppDomain.CurrentDomain.BaseDirectory & "../../Dictionaries/en_us.aff"
Dim dicFile As String = AppDomain.CurrentDomain.BaseDirectory & "../../Dictionaries/en_us.dic"
lbSuggestion.Items.Clear()
lbmorph.Items.Clear()
lbStem.Items.Clear()
Using hunspell As New Hunspell(affFile, dicFile)
Dim correct As Boolean = hunspell.Spell(TextBox1.Text)
checklabel.Text = TextBox1.Text + " is spelled " & (If(correct, "correct", "not correct"))
Dim suggestions As List(Of String) = hunspell.Suggest(TextBox1.Text)
countlabel.Text = "There are " & suggestions.Count.ToString() & " suggestions"
For Each suggestion As String In suggestions
lbSuggestion.Items.Add("Suggestion is: " & suggestion)
Next
Dim morphs As List(Of String) = hunspell.Analyze(TextBox1.Text)
For Each morph As String In morphs
lbmorph.Items.Add("Morph is: " & morph)
Next
Dim stems As List(Of String) = hunspell.Stem(TextBox1.Text)
For Each stem As String In stems
lbStem.Items.Add("Word Stem is: " & stem)
Next
End Using
End Sub
The result,
Hope this can help you.
I am trying to extract an application resource from My.Resources.FILE
I have discovered how to do this with DLL & EXE files, but I still need help with the code for extracting PNG & ICO files.
Other file types also. (If possible)
Here is my current code that works with DLL & EXE files.
Dim File01 As System.IO.FileStream = New System.IO.FileStream("C:\Users\" + Environment.UserName + "\Desktop\" + "SAMPLE.EXE", IO.FileMode.Create)
File01.Write(My.Resources.SAMPLE, 0, My.Resources.SAMPLE.Length)
File01.Close()
First things first, the code you have is bad. When using My.Resources, every time you use a property, you extract a new copy of the data. That means that your second line is getting the data to write twice, with the second time being only to get its length. At the very least, you should be getting the data only once and assigning it to a variable, then using that variable twice. You should also be using a Using statement to create and destroy the FileStream. Even better though, just call File.WriteAllBytes, which means that you don't have to create your own FileStream or know the length of the data to write. You should also not be constructing the file path that way.
Dim filePath = Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "SAMPLE.EXE")
File.WriteAllBytes(filePath, My.Resources.SAMPLE)
As for your question, the important thing to understand here is that it really has nothing to do with resources. The question is really how to save data of any particular type and that is something that you can look up for yourself. When you get the value of a property from My.Resources, the type of the data you get will depend on the type of the file you embedded in first place. In the case of a binary file, e.g. DLL or EXE, you will get back a Byte array and so you save that data to a file in the same way as you would any other Byte array. In the case of an image file, e.g. PNG, you will get back an Image object, so you save that like you would any other Image object, e.g.
Dim filePath = Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "PICTURE.PNG")
Using picture = My.Resources.PICTURE
picture.Save(filePath, picture.RawFormat)
End Using
For an ICO file you will get back an Icon object. I'll leave it to you to research how to save an Icon object to a file.
EDIT:
It's important to identify what the actual problem is that you're trying to solve. You can obviously get an object from My.Resources so that is not the problem. You need to determine what type that object is and determine how to save an object of that type. How to do that will be the same no matter where that object comes from, so the resources part is irrelevant. Think about what it is that you have to do and write a method to do it, then call that method.
In your original case, you could start like this:
Dim data = My.Resources.SAMPLE
Once you have written that - even as you write it - Intellisense will tell you that the data is a Byte array. Your actual problem is now how to save a Byte array to a file, so write a method that does that:
Private Sub SaveToFile(data As Byte(), filePath As String)
'...
End Sub
You can now which you want to do first: write code to call that method as appropriate for your current scenario or write the implementation of the method. There are various specific ways to save binary data, i.e. a Byte array, to a file but, as I said, the simplest is File.WriteAllBytes:
Private Sub SaveToFile(data As Byte(), filePath As String)
File.WriteAllBytes(filePath, data)
End Sub
As for calling the method, you need to data, which you already have, and the file path:
Dim data = My.Resources.SAMPLE
Dim folderPath = My.Computer.FileSystem.SpecialDirectories.Desktop
Dim fileName = "SAMPLE.EXE"
Dim filePath = Path.Combine(folderPath, fileName)
SaveToFile(data, filePath)
Simple enough. You need to follow the same steps for any other resource. If you embedded a PNG file then you would find that the data is an Image object or, more specifically, a Bitmap. Your task is then to learn how to save such an object to a file. It shouldn't take you long to find out that the Image class has its own Save method, so you would use that in your method:
Private Sub SaveToFile(data As Image, filePath As String)
data.Save(filePath, data.RawFormat)
End Sub
The code to call the method is basically as before, with the exception that an image object needs to be disposed when you're done with it:
Dim data = My.Resources.PICTURE
Dim folderPath = My.Computer.FileSystem.SpecialDirectories.Desktop
Dim fileName = "SAMPLE.EXE"
Dim filePath = Path.Combine(folderPath, fileName)
SaveToFile(data, filePath)
data.Dispose()
The proper way to create and dispose an object in a narrow scope like this is with a Using block:
Dim folderPath = My.Computer.FileSystem.SpecialDirectories.Desktop
Dim fileName = "SAMPLE.EXE"
Dim filePath = Path.Combine(folderPath, fileName)
Using data = My.Resources.PICTURE
SaveToFile(data, filePath)
End Using
Now it is up to you to carry out the same steps for an ICO file. If you are a hands on learner then get your hands on.
As i have abandoned the array approach to the problem, i need to know how to make listbox to save in textfile always in program's directory so it can be used/accessed to populate a different listbox, any ideas? Below is my code.
SaveFileDialog1.Filter = "Text files (.txt)|.txt"
SaveFileDialog1.ShowDialog()
If SaveFileDialog1.FileName <> "" Then
Using SW As New IO.StreamWriter(SaveFileDialog1.FileName, False)
For Each itm As String In Me.ListBox1.Items
SW.WriteLine(itm)
Next
End Using
End If
A little bit of research on your part would've helped you understand what you are trying to accomplish better.
How do I get Program Data directory? My.Computer.FileSystem.SpecialDirectories.AllUsersApplicationData
How do I Write multiple lines to file? File.WriteAllLines()
How do I Read multiple lines from a file? File.ReadAllLines()
Once you understand the basics you can easily put them together
Create two List boxes, and one button on your WinForm:
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.
'Get the Program Data Directory (This is hidden by default by the OS.)
Dim strPath As String = My.Computer.FileSystem.SpecialDirectories.AllUsersApplicationData
Dim fileName As String = "myFile.txt"
Dim fullPath = Path.Combine(strPath, fileName)
Dim data As String() = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}
'Save the items to ListBox1 First
For Each item As String In data
ListBox1.Items.Add(item)
Next
'Now write the items to the textfile, line by line.
File.WriteAllLines(fullPath, data)
'Read all lines we just saved and load them onto an array of strings.
Dim tempAllLines() As String = File.ReadAllLines(fullPath)
'Display each on ListBox2 by iterating the array.
For Each line As String In tempAllLines
ListBox2.Items.Add(line)
Next
End Sub
Here, I created this form so you can get an idea of what i'm referring to.
You can get the path to the current executable's folder like this:
folderPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
However, that will only work if the executable is a .NET assembly. Otherwise, you could use the first argument in the command line (which is the full executable file path), like this:
folderPath = Path.GetDirectoryName(Environment.GetCommandLineArgs()(0))
If, on the other hand, you want to get the path of the current assembly (which may be different than the executable that loaded it) you could do this:
folderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
Or, if you want to just get the current directory, you could use this:
folderPath = Directory.GetCurrentDirectory()
Once you have the folder path, you can add the file name to it with Path.Combine, like this:
filePath = Path.Combine(folderPath, fileName)
However, it's not recommended that you write data directly to the program's running path, since the user may not have permission to write to that folder. Using the program data folder would certainly be better, but even that can be risky:
folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyAppName")
The recommended place to store data from .NET apps is Isolated Storage.
I need to get files from a directory containing specific characters in it's name:
The following code below will return any file with the .csv extension. The problem is there are other csv file I need to leave alone or not get.
Dim FileLocation As DirectoryInfo = _
New DirectoryInfo("C:\Folder\Subfolder\Data\Input\")
Dim fi As FileInfo() = FileLocation.GetFiles("*.csv")
Instead of getting any csv file, I would like to get a file with the word data, so any file name containing the word data. Example: *my_data_file.csv*
How do I do this with the code above?
You can update the filter with the string you want to account for (caps will automatically be taken care of):
Dim fi As FileInfo() = FileLocation.GetFiles("*data*.csv")
In any case, bear in mind that this filtering is not "too accurate". For example, the code above would also account for any file (including "data"), whose extension includes csv (e.g., *.csva, *.csvb, etc.). If you want a 100%-reliable approach you should better set up a loop and carry out the filtering "manually"; loops are pretty fast and you wouldn't even notice the difference.
Example of a loop:
Dim fi As List(Of FileInfo) = New List(Of FileInfo)
For Each File In FileLocation.GetFiles()
If (File IsNot Nothing) Then
If (Path.GetExtension(File.ToString.ToLower) = ".csv") Then
If (File.ToString.ToLower.Contains("data")) Then fi.Add(File)
End If
End If
Next
This code will work for sure under your exact requirements and might take care of more complex requests. I have accounted for a List just to show the point clearer.
If you can use LINQ extensions then you can do it this way:
' Get Files {directory} {recursive} {ext} {word in filename}
Private Function Get_Files(ByVal directory As String, _
ByVal recursive As IO.SearchOption, _
ByVal ext As String, _
ByVal with_word_in_filename As String) As List(Of IO.FileInfo)
Return IO.Directory.GetFiles(directory, "*" & If(ext.StartsWith("*"), ext.Substring(1), ext), recursive) _
.Where(Function(o) o.ToLower.Contains(with_word_in_filename.ToLower)) _
.Select(Function(p) New IO.FileInfo(p)).ToList
End Function
Usage example:
For Each file As IO.FileInfo In Get_Files("C:\Folder\Subfolder\Data\Input\", _
IO.SearchOption.TopDirectoryOnly, _
"csv", _
"data")
MsgBox(file.Name)
Next
Replace the wildcard search below "." with your search criteria, for example you want all files that start with name "Hospital*"
Dim Folder As New IO.DirectoryInfo("C:\SampleFolder")
For Each File as IO.FileInfo in Folder.GetFiles("*.*",IO.SearchOption.AllDirectories)
ListBox1.Items.Add(File.FullName)
Next
I would have added this as a comment to the accepted answer, but I do not have enough points to do so:
I just wanted to add varocarbas's answer that, if anyone was wondering (as I was) if this would work in a web scenario as well, it will. Just place the web path inside Server.MapPath() like this:
Dim FileLocation As DirectoryInfo =
New DirectoryInfo(Server.MapPath("/Folder/SubFolder/Data/Input/"))
NOTE: Will NOT work with full url's (no 'http://www.123.com').
Dim Folder As New IO.DirectoryInfo("C:\SampleFolder")
For Each File as IO.FileInfo in Folder.GetFiles("*.*",IO.SearchOption.AllDirectories)
ListBox1.Items.Add(File.FullName)
Application.DoEvents()
Next
I want my program to read certain text in a text file. For example if I have a text file that contains the following info..
acc=blah
pass=hello
I want my vb.net application to get that the account variable is equal to blah, and the password variable is equal to hello.
Can anyone tell me how to do this?
Thanks
Here is a quick little bit of code that, after you click a button, will:
take an input file (in this case I created one called "test.ini")
read in the values as separate lines
do a search, using regular expressions, to see if it contains any "ACC=" or "PASS=" parameters
then write them to the console
here is the code:
Imports System.IO
Imports System.Text.RegularExpressions
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim strFile As String = "Test.INI"
Dim sr As New StreamReader(strFile)
Dim InputString As String
While sr.Peek <> -1
InputString = sr.ReadLine()
checkIfContains(InputString)
InputString = String.Empty
End While
sr.Close()
End Sub
Private Sub checkIfContains(ByVal inputString As String)
Dim outputFile As String = "testOutput.txt"
Dim m As Match
Dim m2 As Match
Dim itemPattern As String = "acc=(\S+)"
Dim itemPattern2 As String = "pass=(\S+)"
m = Regex.Match(inputString, itemPattern, _
RegexOptions.IgnoreCase Or RegexOptions.Compiled)
m2 = Regex.Match(inputString, itemPattern2, _
RegexOptions.IgnoreCase Or RegexOptions.Compiled)
Do While m.Success
Console.WriteLine("Found account {0}", _
m.Groups(1), m.Groups(1).Index)
m = m.NextMatch()
Loop
Do While m2.Success
Console.WriteLine("Found password {0}", _
m2.Groups(1), m2.Groups(1).Index)
m2 = m2.NextMatch()
Loop
End Sub
End Class
Have a look at this article
Reading and writing text files with VB.NET
Wile reading the file line by line, you can use String.Split Method with the splitter being "=", to split the string into param name, and param value.
Looks like you've got an INI file of some kind... The best way to read these is using the *PrivateProfile* functions of the windows API, which means you can actually have a proper full INI file quite easily for anything you need. There is a wrapper class here you may like to use.
Microsoft recommends that you use the registry to store this sort of information though, and discourages use of INI files.
If you wish to just use a file manually with the syntax you have, it is a simple case of splitting the string on '=' and put the results into a Dictionary. Remember to handle cases where the data was not found in the file and you need a default/error. In modern times though, XML is becoming a lot more popular for data text files, and there are lots of libraries to deal with loading from these.
My suggestion: you use XML. The .NET framework has a lot of good XML tools, if you're willing to make the transition to put all the text files into XML, it'll make life a lot easier.
Not what you're looking for, probably, but it's a cleaner solution than anything you could do with plain text (outside of developing your own parser or using a lower level API).
You can't really selectively read a certain bit of information in the file exclusively. You'll have to scan each line of the file and do a search for the string "pass=" at the beginning of the line. I don't know VB but look up these topics:
File readers (espically ones that can read one line at a time)
String tokenizers/splitting (as Astander mentioned)
File reading examples
Have you thought about getting the framework to handle it instead?
If you add an entry into the settings tab of the project properties with name acc, type string, scope user (or application, depending on requirements) and value pass, you can use the System.Configuration.ApplicationSettingsBase functionality to deal with it.
Private _settings As My.MySettings
Private _acc as String
Private _pass as String
Public ReadOnly Property Settings() As System.Configuration.ApplicationSettingsBase
Get
If _settings Is Nothing Then
_settings = New My.MySettings
End If
Return _settings
End Get
End Property
Private Sub SetSettings()
Settings.SettingsKey = Me.Name
Dim theSettings As My.MySettings
theSettings = DirectCast(Settings, My.MySettings)
theSettings.acc=_acc
theSettings.pass=_pass
Settings.Save()
End Sub
Private Sub GetSettings()
Settings.SettingsKey = Me.Name
Dim theSettings As My.MySettings
theSettings = DirectCast(Settings, My.MySettings)
_acc=theSettings.acc
_pass=theSettings.pass
End Sub
Call GetSettings in whatever load event you need, and SetSettings in closing events
This will create an entry in the application.exe.config file, either in your local settings \apps\2.0\etc etc directory, or your roaming one, or if it's a clickonce deployment, in the clickonce data directory. This will look like the following:-
<userSettings>
<MyTestApp.My.MySettings>
<setting name="acc" serializeAs="String">
<value>blah</value>
</setting>
<setting name="pass" serializeAs="String">
<value>hello</value>
</setting>
</MyTestApp.My.MySettings>
</userSettings>
Writing your own parser is not that hard. I managed to make one for a game (Using C#, but VB appears to have Regex class too. Using that, the acc variable in your file would be everything up to the = sign, and then blah would be everything past the = to the newline character (\n) Then go to the next line and repeat.
I have written this for you, check it and enjoy with the results, have a great day!
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim acc As New List(Of String)
Dim pass As New List(Of String)
Dim lines() As String = System.IO.File.ReadAllLines(".\credentials.txt")
For Each lineItem As String In lines
Dim vals() As String = lineItem.Split(Convert.ToChar("="))
If vals.Length > 0 Then
Dim lineId As String = vals(0)
If lineId = "acc" Then
acc.Add(vals(1))
ElseIf lineId = "pass" Then
pass.Add(vals(1))
End If
End If
Next
TextBox_acc.Text = String.Join(Environment.NewLine, acc)
TextBox_pass.Text = String.Join(Environment.NewLine, pass)
End Sub
End Class