vb.net search directory for files containing *.G(num) but NOT *.GP(num) - vb.net

I'm fairly familiar with bash, but I'm very, ***very**** new to vb.net. I'm searching for an easy way to find files in a folder that end with .G1, .G2, .G3, etc. but NOT .GP1, .GP2, .GP3, etc. Then for each file I need to copy it to another folder using a different file name but the same extension. I've managed to figure this out for the unique files, but there will be an undefined number of these depending on the project and I need to make sure that I get them all. Hard coding is possible, but very, very ugly. Any suggestions?
Here's the remnants of a failed attempt:
Public Sub FindGFiles()
FileList = IO.Directory.GetFiles(searchDir, ".G[1-99]" + , IO.SearchOption.AllDirectories)
For Each foundfile As String In FileList
If foundfile.Contains(".G#") Then
'copy file somehow and retain file extension
Else
MsgBox("No match")
End If
Next
End Sub

The GetFiles-method does only support * and ? wildcard characters.
So you have to get all files with a *.G*-extension first.
In the For Each-loop one can then use the Like-operator to check the desired pattern:
Public Sub CopyGFiles(searchDir As String, destDir As String)
Dim fileList As String() = IO.Directory.GetFiles(searchDir, "*.G*", IO.SearchOption.AllDirectories)
Dim fileName As String
Dim extension As String
For Each foundfile As String In fileList
fileName = IO.Path.GetFileNameWithoutExtension(foundfile)
extension = IO.Path.GetExtension(foundfile)
If extension Like ".G#" OrElse
extension Like ".G##" Then
'copy file to destination, append "_new" to the filename and retain file extension
IO.File.Copy(foundfile, IO.Path.Combine(destDir, fileName & "_new" & extension))
Else
'pattern not matched
End If
Next
End Sub
The method-call would then be as follows:
CopyGFiles("C:\Temp", "C:\Temp\Dest")
This should be done inside a Try/Catch as different exceptions can occur when working with files.
Try
CopyGFiles("C:\Temp", "C:\Temp\Dest")
Catch ex As Exception
MessageBox.Show("An error occured" + vbCrLf + ex.Message)
End Try

Related

Moving Files From One Folder To Another VB.Net

I am trying to figure out how to move 5 files
settings.txt
settings2.txt
settings3.txt
settings4.txt
settings5.txt
from one folder to another.
Although I know what the file names will be and what folder Name they will be in, I don't know where that folder will be on the Users computer.
My thought process is to use a FolderBrowseDialog which the user can browse to where the Folder is, and then when OK is pressed, it will perform the File copy to the destination folder, overwriting what's there.
This is what I have so far.
Dim FolderPath As String
Dim result As Windows.Forms.DialogResult = FolderBrowserImport.ShowDialog()
If result = DialogResult.OK Then
FolderPath = FolderBrowserImport.SelectedPath & "\"
My.Computer.FileSystem.CopyFile(
FolderPath & "settings.txt", "c:\test\settings.txt", overwrite:=True)
ElseIf result = DialogResult.Cancel Then
Exit Sub
End If
Rather than run this 5 times, is there a way where it can copy all 5 files at once
I know why IdleMind recommended the approach they did, but it would probably make for a bit more readable code to just list out the file names:
Imports System.IO
...
Dim result = FolderBrowserImport.ShowDialog()
If result <> DialogResult.OK Then Exit Sub
For Each s as String in {"settings.txt", "settings2.txt", "settings3.txt", "settings4.txt", "settings5.txt" }
File.Copy( _
Path.Combine(FolderBrowserImport.SelectedPath, s), _
Path.Combine("c:\test", s), _
True _
)
Next s
You can swap this fixed array out for a list that VB prepares for you:
For Each s as String in Directory.GetFiles(FolderBrowserImport.SelectedPath, "settings*.txt", SearchOption.TopDirectoryOnly)
File.Copy(s, Path.Combine("c:\test", Path.GetFilename(s)), True)
Next s
Tips:
It's usually cleaner to do a If bad Then Exit Sub than a If good Then (big load of indented code) End If - test all your known failure conditions at the start and exit the sub if anything fails, rather than arranging a huge amount of indented code
Use Path.Combine to combine path and filenames etc; it knows how to deal with stray \ characters
Use Imports to import namespaces rather than spelling everything out all the time (System.Windows.Forms.DialogResult - a winforms app will probably have all the necessaries imported already in the partial class so you can just say DialogResult. If you get a red wiggly line, point to the adjacent lightbulb and choose to import System.WIndows/Forms etc)
Once you have the selected folder, use a For loop to build up the names of the files you're looking for. Use System.IO.File.Exists() to see if they are there. Use System.IO.Path.Combine() to properly combine your folders with the filenames.
Here's a full example (without exception handling, which should be added):
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If FolderBrowserImport.ShowDialog() = DialogResult.OK Then
Dim FolderPath As String = FolderBrowserImport.SelectedPath
For i As Integer = 1 To 5
Dim FileName As String = "settings" & If(i = 1, "", i) & ".txt"
Dim FullPathFileName As String = System.IO.Path.Combine(FolderPath, FileName)
If System.IO.File.Exists(FullPathFileName) Then
Dim DestinationFullPathFileName = System.IO.Path.Combine("c:\test", FileName)
My.Computer.FileSystem.CopyFile(FullPathFileName, DestinationFullPathFileName, True)
Else
' possibly do something in here if the file does not exist?
MessageBox.Show("File not found: " & FullPathFileName)
End If
Next
End If
End Sub

Delete A File That Contains The App Name (VB.NET)

This is the code I'm Using:
Dim file As String
Dim prefetchPath As String
Dim FileName As String = My.Application.Info.AssemblyName
prefetchPath = Environment.GetEnvironmentVariable("windir", EnvironmentVariableTarget.Machine) & "\Prefetch"
For Each file In IO.Directory.GetFiles(prefetchPath)
If file.Contains(FileName) Then
IO.File.Delete(file)
End If
Next
i don't know why it does not work if i use FileName. But it work if i use this code
If file.Contains("Example.exe") Then
IO.File.Delete(file)
End If
I want to make sure that if someone changes the name of the application the code works the same way(I already running the file as Administrator)
Help me Thanks.
My guess is that AssemblyName only returns the name without the extension, try including the .exe. Also, it is worth noting that you can use the IO.DirectoryInfo class and pass the file name in the GetFiles method to cut out your For/Each loop.
Here is a quick example:
Dim prefetchPath As String = IO.Path.Combine(Environment.GetEnvironmentVariable("windir", EnvironmentVariableTarget.Machine), "Prefetch")
Dim FileName As String = My.Application.Info.AssemblyName & ".exe"
If New IO.DirectoryInfo(prefetchPath).GetFiles(FileName).Count > 0 Then
IO.File.Delete(IO.Path.Combine(prefetchPath, FileName))
End If

How to Access a txt file in a Folder created inside a VB project

I'm creating a VB project for Quiz App (in VS 2013). So I have some preset questions which are inside the project (I have created a folder inside my project and added a text file).
My question is how can I read and write contents to that file? Or if not is there any way to copy that txt file to Documents/MyAppname when installing the app so that I can edit it from that location?
In the example below I am focusing on accessing files one folder under the executable folder, not in another folder else wheres. Files are read if they exists and then depending on the first character on each line upper or lower case the line then save data back to the same file. Of course there are many ways to work with files, this is but one.
The following, created in the project folder in Solution Explorer a folder named Files, add to text files, textfile1.txt and textfile2.txt. Place several non empty lines in each with each line starting with a character. Each textfile, set in properties under solution explorer Copy to Output Directory to "Copy if newer".
Hopefully this is in tune with what you want. It may or may not work as expected via ClickOnce as I don't use ClickOnce to validate this.
In a form, one button with the following code.
Public Class Form1
Private TextFilePath As String =
IO.Path.Combine(
AppDomain.CurrentDomain.BaseDirectory, "Files")
Private TextFiles As New List(Of String) From
{
"TextFile1.txt",
"TextFile2.txt",
"TextFile3.txt"
}
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim FileName As String = ""
' loop thru each file
For Each fileBaseName As String In TextFiles
FileName = IO.Path.Combine(TextFilePath, fileBaseName)
' only access file if it exist currently
If IO.File.Exists(FileName) Then
' read file into string array
Dim contents As String() = IO.File.ReadAllLines(FileName)
' upper or lower case line based on first char.
' this means you can flip flop on each click on the button
For x As Integer = 0 To contents.Count - 1
If Char.IsUpper(CChar(contents(x))) Then
contents(x) = contents(x).ToLower
Else
contents(x) = contents(x).ToUpper
End If
Next
' save changes, being pesstimistic so we use a try-catch
Try
IO.File.WriteAllLines(FileName, contents)
Catch ex As Exception
Console.WriteLine("Attempted to save {0} failed. Error: {1}",
FileName,
ex.Message)
End Try
Else
Console.WriteLine("Does not exists {0}", FileName)
End If
Next
End Sub
End Class
This may help you
Dim objStreamReader As StreamReader
Dim strLine As String
'Pass the file path and the file name to the StreamReader constructor.
objStreamReader = New StreamReader("C:\Boot.ini")
'Read the first line of text.
strLine = objStreamReader.ReadLine
'Continue to read until you reach the end of the file.
Do While Not strLine Is Nothing
'Write the line to the Console window.
Console.WriteLine(strLine)
'Read the next line.
strLine = objStreamReader.ReadLine
Loop
'Close the file.
objStreamReader.Close()
Console.ReadLine()
You can also check this link.

How to get the file name of a file in VB?

I make a search program for searching a list of files in a computer and then copy the file into a store folder. The file name could be "*11*2.txt" As long as the program find this pattern, it should copy to the store folder. The problem is that I don't know the exactly name of the file before the search and I don't want to rename the file, I don't know how to save the file. Please help
I use the following to find the file, which does its work
Public Sub DirSearch(ByVal sDir As String, ByVal FileName As String)
Dim To_Path As String
To_Path = Form1.TextBox5.Text
For Each foundFile As String In My.Computer.FileSystem.GetFiles(sDir, FileIO.SearchOption.SearchAllSubDirectories, FileName)
Copy2Local(foundFile, To_Path)
Next
End Sub
Here is the current version of the Copy2Local (Note: it is not working right)
Public Sub Copy2Local(ByVal Copy_From_Path As String, ByVal Copy_To_Path As String)
' Specify the directories you want to manipulate.
Try
Dim fs As FileStream = File.Create(Copy_From_Path)
fs.Close()
' Copy the file.
File.Copy(Copy_From_Path, Copy_To_Path)
Catch
End Try
End Sub
First, you should check if ToPath is a valid directory since it's coming from a TextBox:
Dim isValidDir = Directory.Exists(ToPath)
Second, you can use Path.Combine to create a path from separate (sub)directories or file-names:
Dim copyToDir = Path.GetDirectoryName(Copy_To_Path)
Dim file = Path.GetFileName(Copy_From_Path)
Dim newPath = Path.Combine(copyToDir, file)
http://msdn.microsoft.com/en-us/library/system.io.path.aspx
(disclaimer: typed from a mobile)
To answer your question: You can get the file name with Path.GetFileName. Example:
Dim fileName As String = Path.GetFileName(foundFile)
However, there's a bunch of other things wrong with your code:
Here,
Dim fs As FileStream = File.Create(Copy_From_Path)
fs.Close()
you are overwriting your source file. This does not seem like a good idea. ;-)
And here,
Try
...
Catch
' Do Nothing
End Try
You are throwing away exceptions that would help you find and diagnose problems. Don't do that. It makes debugging a nightmare.
In vb.net, I'm using the following code to find the filename
Textbox1.Text = New FileInfo(OpenFileDialog.FileName).Name
this code work fine with open file dialog box

ASP.NET How do I wait for file upload/release?

I've got ASP.NET intranet application written in VB. It gets a file from the user, and then depending on a few different cases it may create a few copies of the file as well as move the original.
Unfortunately I've come across a case where I get this error:
Exception Details: System.IO.IOException: The process cannot access the file
'\\some\dir\D09_03_5_180_0.000-6.788.png' because it is being used by
another process.
Which is thrown by My.Computer.FileSystem.CopyFile. And that's fine that it's being used by another process - it may still be saving/downloading from the user or trying to copy while another thread(?) is copying, I don't really care about that, what I want to know:
Is there any way that I can tell VB to wait to copy (also move) the file until the file is no longer in use?
Thanks
Test if the file is in use and the do what you need to do.
Public Sub WriteLogFile(ByVal pText As String, ByVal psPath As String, ByVal psName As String)
Dim strFullFileName As String
Dim Writer As System.IO.StreamWriter
Dim Fs As System.IO.FileStream
Try
Dim DirectoryHandler As New System.IO.DirectoryInfo(psPath)
strFullFileName = psPath & "\" & psName & Date.Today.Month.ToString & "-" & Date.Today.Day.ToString & "-" & Date.Today.Year.ToString & ".txt"
If Not DirectoryHandler.Exists() Then
Try
Monitor.Enter(fsLocker)
DirectoryHandler.Create()
Finally
Monitor.Exit(fsLocker)
End Try
End If
Try
If CheckIfFileIsInUse(strFullFileName) = True Then
Thread.Sleep(500) ' wait for .5 second
WriteLogFile(pText, psPath, psName)
If Not Fs Is Nothing Then Fs.Close()
If Not Writer Is Nothing Then Writer.Close()
Exit Sub
End If
Monitor.Enter(fsLocker)
Fs = New System.IO.FileStream(strFullFileName, IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.Write)
Writer = New System.IO.StreamWriter(Fs)
Writer.WriteLine(Date.Now.ToString & vbTab & "ProcessID: " & Process.GetCurrentProcess.Id.ToString() & vbTab & pText)
Writer.Close()
Fs.Close()
Finally
Monitor.Exit(fsLocker)
End Try
Catch ex As Exception
Dim evtEMailLog As System.Diagnostics.EventLog = New System.Diagnostics.EventLog()
evtEMailLog.Source = Process.GetCurrentProcess.ProcessName.ToString()
evtEMailLog.WriteEntry(ex.Message, System.Diagnostics.EventLogEntryType.Error)
Finally
If Not Fs Is Nothing Then Fs.Close()
If Not Writer Is Nothing Then Writer.Close()
End Try
End Sub
Public Function CheckIfFileIsInUse(ByVal sFile As String) As Boolean
If System.IO.File.Exists(sFile) Then
Try
Dim F As Short = FreeFile()
FileOpen(F, sFile, OpenMode.Append, OpenAccess.Write, OpenShare.Shared)
FileClose(F)
Catch
Return True
End Try
End If
End Function
Hmm... not directly.
What most implementations are doing, is making a retry of copying the file, with a small timeframe (some seconds)
if you want to make a nice UI, you check via Ajax, if the copying process went well.
Well, it turns out that waiting would not work in this case:
When trying to copy a file you cannot copy a file from one location to the same location or it will throw an error (apparently). Rather than just pretending to copy the file, VB actually tries to copy the file and fails because the copy operation is trying to copy to the file it's copying from (with overwrite:=True at least).
Whoops!