Rename a file extension in VB.NET - vb.net

I've written a data sorter which writes out a .build extension to the files it's writing to so nothing tries to lift it as it's writing data to particular files.
At the end, I want to rename anything with a .build extension to a .dat before the program closes.
For Each f In outputFiles
For Each r In TrailerRecords
' Set the bill count variable
If r.VariableField Then
r.Fields(1) = String.Format("{0:000000}", f.Value)
End If
' Write the trailer record to the output file
File.AppendAllText(f.Key, r.ToString() & vbLf)
Next
' Rename all.build files to .dat
NEEDS TO GO HERE
' Copy each output file to the backup directory
File.Copy(f.Key, Path.Combine(backupFolder, Path.GetFileName(f.Key)), True)
Next
End Sub

Get the files and rename it:
Dim auxFile as String
Dim files() As String = IO.Directory.GetFiles(myFolderPath, "*.build")
For Each sFile As String In files
auxFile = IO.Path.GetFileNameWithoutExtension(sFile) & ".dat"
My.Computer.FileSystem.RenameFile(sFile, auxFile)
Next
You can use File.Copy() with the overwrite property to True instead.
Take a look at the MSDN documentation:
GetFiles
RenameFile
Copy
GetFilenameWithoutExtension

Related

Remove double quotes in the content of text files

I am using a legacy application where all the source code is in vb.net. I am checking if the file exists and if the condition is true replace all the " in the contents of the file. For instance "text" to be replaced as text. I am using the below code.
vb.net
Dim FileFullPath As String
FileFullPath = "\\Fileshare\text\sample.txt"
If File.Exists(FileFullPath) Then
Dim stripquote As String = FileFullPath
stripquote = stripquote.Replace("""", "").Trim()
Else
'
End If
I get no errors and at the same time the " is not being replaced in the content of the file.
Data:
ID, Date, Phone, Comments
1,05/13/2021,"123-000-1234","text1"
2,05/13/2021,"123-000-2345","text2"
3,05/13/2021,"123-000-3456","text2"
Output:
1,05/13/2021,123-000-1234,text1
2,05/13/2021,123-000-2345,text2
3,05/13/2021,123-000-3456,text2
You can read each line of the file, remove the double-quotes, write that to a temporary file, then when all the lines are done delete the original and move/rename the temporary file as the filename:
Imports System.IO
'...
Sub RemoveDoubleQuotes(filename As String)
Dim tmpFilename = Path.GetTempFileName()
Using sr As New StreamReader(filename)
Using sw As New StreamWriter(tmpFilename)
While Not sr.EndOfStream
sw.WriteLine(sr.ReadLine().Replace("""", ""))
End While
End Using
End Using
File.Delete(filename)
File.Move(tmpFilename, filename)
End Sub
Add error handling as desired.
The best way to go about this depends on the potential size of the file. If the file is relatively small then there's no point processing it line by line and certainly not using a TextFieldParser. Just read the data in, process it and write it out:
File.WriteAllText(FileFullPath,
File.ReadAllText(FileFullPath).
Replace(ControlChars.Quote, String.Empty))
Only if the file is potentially large and reading it all in one go would require too much memory should you consider processing it line by line. In that case, I'd go this way:
'Let the system create a temp file.
Dim tempFilePath = Path.GetTempFileName()
'Open the temp file for writing text.
Using tempFile As New StreamWriter(tempFilePath)
'Open the source file and read it line by line.
For Each line In File.ReadLines(FileFullPath)
'Remove double-quotes from the current line and write the result to the temp file.
tempFile.WriteLine(line.Replace(ControlChars.Quote, String.Empty))
Next
End Using
'Overwrite the source file with the temp file.
File.Move(tempFilePath, FileFullPath, True)
Note the use of File.ReadLines rather than File.ReadAllLines. The former will only read one line at a time where the latter reads every line before you can process any of them.
EDIT:
Note that this:
File.Move(tempFilePath, FileFullPath, True)
only works in .NET Core 3.0 and later, including .NET 5.0. If you're targeting .NET Framework then you have three other options:
Delete the original file (File.Delete) and then move the temp file (File.Move).
Copy the temp file (File.Copy) and then delete the temp file (File.Delete).
Call My.Computer.FileSystem.MoveFile to move the temp file and overwrite the original file in one go.
TextFieldParser is probably the way to go.
Your code with a few changes.
Static doubleQ As String = New String(ControlChars.Quote, 2)
Dim FileFullPath As String
FileFullPath = "\\Fileshare\text\sample.txt"
If IO.File.Exists(FileFullPath) Then
Dim stripquote As String = IO.File.ReadAllText(FileFullPath)
stripquote = stripquote.Replace(doubleQ, "").Trim()
Else
'
End If
Note the static declaration. I adopted this approach because it confused the heck out of me.

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

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

Convert multiple .xls files to .xlsx in ssis

I have a folder that receives multiple excel files in .xls format. I need to change the format type to .xlsx in order to load the excel data into SQLvia SSIS. I know how to rename the file using "File System Task" but that works for a specific file. but my file contains a file # and date as well that needs to stay same as source file, I only want the file type to change and the file move to a processed folder. Can anyone help me?
Source Path: C:\Documents\TestFolder
Source File: TestSegRpt_0001_2017_02_22.xls
Destination Path: C:\Documents\TestFolderProcessed
Destination File: TestSegRpt_0001_2017_02_22.xlsx
Hoping i understood your problem correctly.
I think below link will help.
https://answers.microsoft.com/en-us/msoffice/forum/msoffice_excel-mso_other/batch-convert-xls-to-xlsx/1d9b3d78-daf0-4014-8fb2-930aca6493b0
You have to add a Script Task, loop over files, and use a function like the following to create precessed directory and convert files (code in Vb.net):
Public Sub ConvertXlsToXlsx(ByVal strpath as string)
Dim strDirectory as string = System.IO.Path.GetDirectoryName(strpath) & "Processed"
If Not System.IO.Directory.Exists(strDirectory) Then System.IO.Directory.CreateDirectory(strDirectory)
Dim xl As New Microsoft.Office.Interop.Excel.Application
Dim xlBook As Microsoft.Office.Interop.Excel.Workbook
xlWorkBook = xl.Workbooks.Open(strpath)
xlBook.SaveAs(strDirectory & "\" & System.IO.Path.GetFilename(strpath) & "x")
xl.Application.Workbooks.Close()
xl.Application.Quit()
End Sub
Your code will look like:
Public Sub Main
Dim strFolder as string = Dts.Variables.Item("FolderPath").Value
Dim strXlsFiles() as string = IO.Directory.GetFiles(strFolder,"*.xlsx",SearchOption.TopDirectoryOnly)
For each strFile as String in strXlsFiles
If strFile.EndsWith("xlsx") The Continue For
ConvertXlsToXlsx(strFile)
Next
End Sub
Reference:
https://social.msdn.microsoft.com/Forums/office/en-US/a73f846c-91ee-4dad-bd7b-c04d418d0561/convert-xls-into-xlsx?forum=exceldev

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.

VB.NET file error 75 - Path/File Access Error - how is my file locked? I need to delete it

i'm getting a error 75 - file/path access error when i attempt to delete my file (last lines of the code block below):
' make a reference to a directory
Dim directory As New IO.DirectoryInfo(WatchDirectory) 'ex C:\Print\Realtime\
Dim directoryList As IO.FileInfo() = directory.GetFiles(WatchFilter) 'ex *.xml
Dim directoryFile As IO.FileInfo
'list the names of all files in the specified directory
For Each directoryFile In directoryList
'scans the Realtime folder (WatchDirectory) for each specified file (WatchFilter / xml) for processing.
If directoryFile.Name = RealTimeFile Then
'checks if the file is realtime by matching the name up to the ProcessRealtimeFile app setting (ex realtime.xml)
Continue For
Else
'this is not a ProcessRealtimeFile app setting (ex realtime.xml) file
Dim Name As String
Dim renameRetries As Integer = 5
'get file name without extension
Name = IO.Path.GetFileNameWithoutExtension(directoryFile.Name)
While True
Try
If File.Exists(ProcessDirectory & RealTimeFile) = False Then
'the current file to be checked against in the watch directory does not exist in the processdirectory (ex. C:\Print\Oracle\xml.rt\). continue.
Log.Write(Log.Level.Information, "RTPrint-Diamond", Environment.UserName, Environment.MachineName, "File " & directoryFile.FullName & " is being processed by scrape.")
If ArchiveXML = True Then
'copy the current file to the archive directory (ex C:\print\xml.rt\archive\), overwriting the existing file if exists
System.IO.File.Copy(directoryFile.FullName, ArchiveDirectory & directoryFile.Name, True)
End If
'update the date and time of the active file to now
System.IO.File.SetLastWriteTime(directoryFile.FullName, Date.Now)
Log.Write(Log.Level.Information, "RTPrint-Diamond", Environment.UserName, Environment.MachineName, "Date Changed.")
If ISPublisher(directoryFile.FullName) Then
'Current file is a publisher file. Process
Dim fileInfo As New IO.FileInfo(directoryFile.FullName)
Dim utf8WithoutBOM As New System.Text.UTF8Encoding(False) 'file encoding type - UTF8 w/o BOM
Using writer As StreamWriter = New StreamWriter(Path.Combine(PublisherProcessDirectory, directoryFile.Name), False, utf8WithoutBOM)
'set up write to the publisher process directory (ex C:\print5x\xml.rt\)
'publisher requires utf8 w/o BOM to read the file. We need to change the encoding type to this standard.
'this converts the file to utf8 w/o BOM to the 5x output destination
Using reader As StreamReader = fileInfo.OpenText
While Not reader.EndOfStream
Dim line As String = reader.ReadLine
writer.Write(line & vbCrLf)
End While
reader.Close()
End Using
writer.Close()
End Using
If File.Exists(Path.Combine(PublisherProcessDirectory, directoryFile.Name)) Then
'make sure the destination file was successfully re-written in utf8 w/o bom and delete the source file
If IsFileOpen(directoryFile.FullName, 1) = True Then
Microsoft.VisualBasic.FileClose(1)
End If
System.IO.File.Delete(directoryFile.FullName)
End If
I even tested with some sample solutions I read on this site to run a function test to see if the lock is present (giving error 75), and if true is returned, attempt a file close which also is not doing anything.
Obviously my writer.Close() is not doing the job. Can anyone spot why the System.IO.File.Delete(directoryFile.FullName) is not allowing me access to this text file for deletion, and how i can unlock it to delete? Is it the for each that is locking my file? I need to delete the file within the loop, so if the for loop is locking me, what are the work-arounds here?
Additionally, i tested the delete by removing the entire writer block and 2 declared variables above it, and the file still had a lock. This can help to isolate the issue to the surrounding logic and not the streamWriter portion.
Thanks in advance!