VB.net Null Characters - vb.net

I am appending a very large text file, however when it is complete and I go to view it i get the following error. Null characters (00H) contained in file.
This is the code I'm using to read all the text files to one large text file. I am opening the large file in EmEditor.
Any help gratefully received.
Dim Paths() As String = Directory.GetFiles("c:\logs1", "main_access_log.*", SearchOption.AllDirectories)
System.Windows.Forms.Cursor.Current = Cursors.WaitCursor
For Each Path As String In Paths
File.AppendAllText("c:\logs1\zmaster.txt", File.ReadAllText(Path), Encoding.Default)
Next
System.Windows.Forms.Cursor.Current = Cursors.Default
MessageBox.Show("Master File Created")

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.

Illegal Characters in path when grabbing text from a file?

I'm getting illegal characters in path, but the directory (the path) will be different for everyone, so I'm not setting a value for the "path", it's what the user chooses in the file explorer.
I haven't seen a solution for VB.net yet so here's the code I have now:
myFileDlog.InitialDirectory = "c:\"
myFileDlog.Filter = "Txt Files (*.txt)|*.txt"
myFileDlog.FilterIndex = 2
myFileDlog.RestoreDirectory = True
If myFileDlog.ShowDialog() =
DialogResult.OK Then
If Dir(myFileDlog.FileName) <> "" Then
Else
MsgBox("File Not Found",
MsgBoxStyle.Critical)
End If
End If
'Adds the file directory to the text box
TextBox1.Text = myFileDlog.FileName
Dim fileReader As String
fileReader = My.Computer.FileSystem.ReadAllText(myFileDlog.FileName)
Dim lines() As String = IO.File.ReadAllLines(fileReader)
At Dim lines() As String = IO.File.ReadAllLines(fileReader)
It breaks with the Illegal Characters in Path exception, and I'm not sure how to test where the illegal character is, because it's grabbing from your own file directory. Any help with this?
The problem originated from this line:
Dim fileReader As String = My.Computer.FileSystem.ReadAllText(myFileDlog.FileName)
fileReader takes all string contents from the corresponding file name and pass it into File.ReadAllLines method at next line, throwing ArgumentException with illegal file path message if illegal characters found inline.
Correct way to read file contents using ReadAllLines is using predefined file path or directly using FileDialog.FileName property as argument given below:
Using myFileDlog As OpenFileDialog = New OpenFileDialog()
' set dialog filters here
If (myFileDlog.ShowDialog() = DialogResult.OK) Then
If Dir(myFileDlog.FileName) <> "" Then
Dim lines() As String = File.ReadAllLines(myFileDlog.FileName)
For Each line As String In lines
' do something with file contents
Next
Else
' show "file not found" message box
End If
End If
End Using
Since ReadAllLines already being used to fetch all file contents, usage of ReadAllText may be unnecessary there.

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 can i open more than 1000 files using openfiledialog? Or is there any method i can use?

I am writing a small program in which user will select set of file (mostly .CSV) files and my program will search through them and find required data.
It's working for up to 300 files, but after that its not working. It's giving me an error:
InvalidOperationExceprion was Unhandaled
Too Many files are selected. Select Fewer files and try again.
What should i do?
Like Eric Walker said, open file dialog works with 1,000's and 1,000's of files, there is no reason why it would stop at 300.
The best way to loop though files/folders to get info is to use the .GetFiles() method
Dim OFD As New FolderBrowserDialog
If OFD.ShowDialog = DialogResult.OK Then
For Each f In Directory.GetFiles(OFD.SelectedPath)
If Path.GetExtension(f) = ".txt" Path.GetExtension(f) = ".csv" Then
Dim reader As String() = File.ReadAllLines(f)
For each line as String in reader
DoSomethingAwesome(line)
Next
End If
Next
End If
This will cycle through every file in a certain Directory.
Now if you would like to cycle through every file in a file dialog, then you would use this.
Dim OFD As New OpenFileDialog()
OFD.Multiselect = True
If OFD.ShowDialog = DialogResult.OK Then
For Each f In OFD.FileNames
If Path.GetExtension(f) = ".txt" Path.GetExtension(f) = ".csv" Then
Dim reader As String() = File.ReadAllLines(f)
For Each line As String In reader
DoSomethingAwesome(line)
Next
End If
Next
End If
Give one of these a try depending on your preference.
As a side note, for future posts - please post your attempted code or more details on what you are trying to accomplish and where you are having trouble. Frankly, Im surprised you weren't downvoted (very surprised, people on SO can be ruthless). Just a friendly tip.

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!