In vb.net, how do I use directory info with specific files name in the query - vb.net

Lets say I have a list of files separated by a comma.
Dim listOfFiles As String() = filesPosted.Split(",")
And I use DirectoryInfo to grab that list of files and send it to another array.
Dim files = New DirectoryInfo(StorageRoot) _
.GetFiles("*", SearchOption.TopDirectoryOnly) _
.Where(Function(f) Not f.Attributes.HasFlag(FileAttributes.Hidden)) _
.Where(Function(f) filesPosted.Contains(f.Name)) _
.[Select](Function(f) New FilesStatus(f)).ToArray()
The problem I'm facing is, I need my condition to be more strict. I'll explain:
If my listOfFiles contains ( abc.txt, xyz.txt ) and there's a filename of aabc.txt in the directory that is being searched, it'll return both abc.txt and aabc.txt. I know this is because of this part of the clause:
.Where(Function(f) filesPosted.Contains(f.Name))
As the contains attribute is finding this other file... But I don't want it. I want the files to match exactly based on the string().
Is there a better way to do this without cycling through each file? A tighter way to make it a strict condition on "Contains" ?
Thank you for your help!

Try:
Dim listOfFiles As String() = filesPosted.Split(",").Select(function(f) f.ToLower())
' then
Dim files = New DirectoryInfo(StorageRoot) _
.GetFiles("*", SearchOption.TopDirectoryOnly) _
.Where(Function(f) Not f.Attributes.HasFlag(FileAttributes.Hidden)) _
.Where(Function(f) listOfFiles.Any(function(l) l = f.Name.ToLower())) _
.[Select](Function(f) New FilesStatus(f)).ToArray()
Sorry, poor C# to VB.Net conversion

Related

VB.NET / First row missing when writing to a CSV file

Wrote a program that writes name, postcode, device type, damage type to a CSV file and for some reason it misses the first row.
Thanks
Sub fileWriting(ByVal file As String, ByVal name As String, ByVal postcode As String, ByVal dmgType As String, ByVal devType As String) ' writing to files function
Dim ObjStreamWriter As StreamWriter
ObjStreamWriter = New StreamWriter(file, True)
ObjStreamWriter.Write(name & ",")
ObjStreamWriter.Write(postcode & ",")
ObjStreamWriter.Write(dmgType & ",")
ObjStreamWriter.WriteLine(devType)
ObjStreamWriter.Close()
End Sub
One point on the code above:
ObjStreamWriter = New StreamWriter(file, True)
will append to an existing file, if the file already exists. Therefore the text you're appending may exist further down in the file depending how much you've already written.
Additionally, StreamWriter implements IDisposable so the preferred method of implementation is to instantiate it in a Using block, if you're immediately closing the object.
Using ObjStreamWriter = New StreamWriter(file, True)
ObjStreamWriter.Write(name & ",")
ObjStreamWriter.Write(postcode & ",")
ObjStreamWriter.Write(dmgType & ",")
ObjStreamWriter.WriteLine(devType)
End Using
I'm not sure if these will fix your issue as there's insufficient code to really determine that, but if you're having issues with text not flushing, this ensures that you're automatically doing everything needed to properly close the file. Normally that'd be text missing from the end of the file, not the start, but it might help.

VB.Net / forms - Creating Folders with unique ID Numbers

I need to have a button that once clicked will create a folder in a pre-specified directory. The folder in question would contain a number with the year and 3 additional numbers in sequence. Formatted like this "2022001 Folder Name Generated From Text Box Here"
Once the user clicks the button again it adds +1 to the next folder ID "2022002 Folder Name Generated From Text Box Here"
The number would have to be stored so it could pick up where it left off after the program is closed.
What is the best way to go about doing this? Could you share a snippit?
This works for me:
Dim year = DateTime.Now.Year
Dim regex = New Regex($"{year:0000}(\d{{3}})")
Dim nextNumber = _
Directory _
.EnumerateDirectories("D:\Temporary") _
.Select(Function(x) New DirectoryInfo(x)) _
.Select(Function(x) regex.Match(x.Name)) _
.Where(Function(x) x.Success) _
.Select(Function(x) Integer.Parse(x.Groups(1).Value)) _
.Max() + 1
Dim nextFolder = $"{year}{nextNumber:000}"
When I created these two folders 2022001 & 2022002 - Copy and ran this code it produced:
2022003

In vb.net, how do I get files from a directory based on a comma separated string?

I need to create an array() from files in a folder. Here's an example of how I would get all files within a folder.
Dim filesList = New DirectoryInfo("MyPath").GetFiles("*", SearchOption.TopDirectoryOnly).Where(Function(f) Not f.Attributes.HasFlag(FileAttributes.Hidden)).[Select](Function(f) New AClassNameHere(f)).ToArray()
I want to do the exact same thing, but only get files that exist in a comma separated string.
Dim myFiles as String = "filename1.jpg,filename2.jpg,filename3.jpg"
Where you see the AClassNameHere is a class I need to send each file to, and it would also be great if I knew how to send additional data about each file, like its type, size, etc.
Thank you kindly!
You could narrow the query results by adding an additional .Where() filter
Dim myFiles as String = "filename1.jpg,filename2.jpg,filename3.jpg"
Dim filesList = New DirectoryInfo("MyPath")
.GetFiles("*", SearchOption.TopDirectoryOnly)
.Where(Function(f) Not f.Attributes.HasFlag(FileAttributes.Hidden))
.Where(Function(f) myFiles.Contains(f.Name))
.[Select](Function(f) New AClassNameHere(f)).ToArray()
A better option would be to ensure that all filenames follow a pattern.
New DirectoryInfo("MyPath").GetFiles("filename*.jpg", SearchOption.TopDirectoryOnly)
Use this...
Dim Files() As String
Files= filesList.Split(",")
For each File In Files
Msgbox(File)
Next

How to find or get files in Directory with Specific word in the file name Visual Basic.net?

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

replace file name have multiple extensions in vb.net

I have an issue while uploading documents have multiple periods. For example if I upload a file having an extension of ammu.gopu.docx. I would like to replace that as ammu_gopu.docx, means to preserve the extension and replace the file name with undescore.
This should do what your asking. Beware - If your file name also appears in the path it will also be updated.
Dim fullPath As String = "C:\Test\My.File.Name.txt"
Dim fileName As String = IO.Path.GetFileNameWithoutExtension(fullPath)
fullPath = fullPath.Replace(fileName, fileName.Replace("."c, "-"))
Use the System.IO.Path.GetExtension method.
Try this:
filePath = IO.Path.GetDirectoryName(filePath) & _
IO.Path.GetFileNameWithoutExtension(filePath).Replace("."c, "_"c) & _
"." & IO.Path.GetExtension(filePath)