VB.net program hangs when asked to read .txt - vb.net

I am attempting to read a .txt file that I successfully wrote with a separate program, but I keep getting the program stalling (aka no input/output at all, like it had an infinite loop or something). I get the message "A", but no others.
I've seen a lot of threads on sites like this one that list all sorts of creative ways to read from a file, but every guide I have found wants me to change the code between Msgbox A and Msgbox D. None of them change the result, so I'm beginning to think that the issue is actually with how I'm pointing out the file's location. There was one code (had something to do with Dim objReader As New System.IO.TextReader(FileLoc)), but when I asked for a read of the file I got the file's address instead. That's why I suspect I'm pointing to the .txt wrong. There is one issue...
I have absolutely no idea how to do this, if what I've done is wrong.
I've attached at the end the snippet of code (with every single line of extraneous data ripped out of it).
If it matters, the location of the actual program is in the "G01-Cartography" folder.
Private Sub GameMain_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
LoadMap("Map_Cygnus.txt")
End Sub
Private Sub LoadMap(FileLoc As String)
FileLoc = "C:\Users\Adam\Documents\Visual Studio 2013\Projects\G01-Cartography\Maps\" + FileLoc
MsgBox("A")
Using File As New StreamReader(FileLoc)
MsgBox("B")
Dim WholeMap = File.ReadLine()
MsgBox("C")
End Using
MsgBox("D")
End Sub

What does running this show you in the debugger? Can you open the Map_Cygnus.txt file in Notepad? Set a breakpoint on the first line and run the program to see what is going on.
Private BaseDirectory As String = "C:\Users\Adam\Documents\Visual Studio 2013\Projects\G01-Cartography\Maps\"
Private Sub GameMain_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim WholeMap = File.ReadAllText(Path.Combine(BaseDirectory, "Map_Cygnus.txt"))
Debug.Print("Size Of Map: {0}", WholeMap.Length)
End Sub

It looks like you're using the correct methods/objects according to MSDN.
Your code runs for me in an new VB console app(.net 4.5)
A different approach then MSGBOXs would be to use Debug.WriteLine or Console.WriteLine.
If MSGBOX A shows but not B, then the problem is in constructing the stream reader.
Probably you are watching the application for output but the debugger(visual studio) has stopped the application on that line, with an exception. eg File not found, No Permission, using a http uri...
If MSGBOX C doesn't show then problem is probably that the file has problems being read.
Permissions?
Does it have a Line of Text?
Is the folder 'online'
If MSGBOX D shows, but nothing happens then you are doing nothing with WholeMap
See what is displayed if you rewite MsgBox("C") to Debug.WriteLine("Read " + WholeMap)

I have a few suggestions. Firstly, use Option Strict On, it will help you to avoid headaches down the road.
The code to open the file is correct. In addition to avoiding using MsgBox() to debug and instead setting breakpoints or using Debug.WriteLine(), wrap the subroutine in a Try...Catch exception.
Private Sub GameMain_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
LoadMap("Map_Cygnus.txt")
End Sub
Private Sub LoadMap(FileLoc As String)
Try
FileLoc = "C:\Users\Adam\Documents\Visual Studio 2013\Projects\G01-Cartography\Maps\" + FileLoc
MsgBox("A")
Using File As New StreamReader(FileLoc)
MsgBox("B")
Dim WholeMap = File.ReadLine() 'dimming a variable inside a block like this means the variable only has scope while inside the block
MsgBox("C")
End Using
MsgBox("D")
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Note that you normally should only catch whatever exceptions you expect, but I generally catch everything while debugging things like this.
I would also like to point out that you are only reading one line out of the file into the variable WholeMap. That variable loses scope as soon as the End Using line is hit, thereby losing the line you just read from the file. I'm assuming that you have the code in this way because it seems to be giving you trouble reading from it, but thought I would point it out anyway.
Public Class GameMain
Private WholeMap As String = ""
Private Sub GameMain_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
LoadMap("Map_Cygnus.txt")
End Sub
Private Sub LoadMap(FileLoc As String)
Try
FileLoc = "C:\Users\Adam\Documents\Visual Studio 2013\Projects\G01-Cartography\Maps\" + FileLoc
Using File As New StreamReader(FileLoc)
WholeMap = File.ReadLine() 'dimming the variable above will give all of your subs inside class Form1 access to the contents of it (note that I've removed the Dim command here)
End Using
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
End Class

Related

VB.et FileSystemWatcher Event Handler - Calls of Handler Repeats (Unwanted)

I'm trying to log file activity in a directory with the FileSystemWatch class by adding the file to a custom class within a list, unfortunately, it seems that when copying a file or adding a new file to the target directory, it's running 4 times instead of once.
When adding a file to the directory, the AddressOf Sub will write 3 to 4 times instead of just once. I'm not sure why.
Here's the code snippet.
Public fileTypefilter As String = "*.xlsx"
Public DesDir As String = "C:\"
Public EventLog As List(Of FileEvent)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim watchDir As String = DesDir
Dim watch As New FileSystemWatcher(watchDir)
Me.Text = "Monitoring " & watch.Path
watch.IncludeSubdirectories = false
watch.Filter = "*.xlsx"
AddHandler watch.Changed, AddressOf watch_Changed
watch.EnableRaisingEvents = True
End Sub
Private Sub watch_Changed(ByVal sender As Object, ByVal e As FileSystemEventArgs)
Try
EventLog.Add(New FileEvent(e.FullPath))
Exit Sub
Catch ex As NullReferenceException
EventLog = New List(Of FileEvent)({New FileEvent(e.FullPath)})
Exit Sub
End Try
End Sub
The Changed event handler is executed multiple times because multiple changes occur. As is ALWAYS the case, you should have read the relevant documentation for yourself first, which says:
The change of a file or folder. The types of changes include: changes to size, attributes, security settings, last write, and last access time.
If you don't want to log each individual change then you need to filter them somehow. For instance, you might want to record the time a change occurred for a particular path and then not log a change if some minimum time has not elapsed since the last change for the same path.
There would also be the option of using a HashSet instead of a List. That could be configured to use an appropriate equality comparer and then you could call Add as many times as you like for the same path and it will only be added once. That would mean that, were a set of changes to occur later for the same path, those would not be logged. I'm not sure whether that would be an issue for you or not.

Error with VB ParseFileText method

When I run this I made a dummy "Button1" to test populate the fields they will successfully fill out the texts boxes. How ever I will have it parse that file every minute, and when I do it again I get the error shown below. By adding the routine "DisplayForm_Load" to the button1_click even it would work fine.
My question is I'm pretty sure I shouldn't have to redefine this every time? I think I'm not setting the index back to 0 or something along those lines. From what I've been able to understand from MS website is its like its indexing things in the array that don't exist.
Error received:
An unhandled exception of type 'System.IndexOutOfRangeException' occurred in WindowsApplication4.exe
Imports Microsoft.VisualBasic.FileIO
Public Class Form1
Private Directory As String ' Used to hold the folder directory to push/pull data from.
Private FileParser As Microsoft.VisualBasic.FileIO.TextFieldParser
Private Sub PushButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles PushButton.Click
' Sends information to txt file.
' This bit works fine, just writes code to txt file that can be parsed below.
End Sub
Sub DefineTextFieldParse_Load() Handles MyBase.Load
' Instantiate teh TextFieldParser and the set the delimiter
Dim FileName As String = "C:\Users\Caleb\Documents\TestDoc.txt"
Try
FileParser = New FileIO.TextFieldParser(FileName) '' Selects File to Parse
FileParser.TextFieldType = FieldType.Delimited
FileParser.SetDelimiters(",")
Catch ex As Exception
' Errors
MessageBox.Show("Unable to read the file" & "," & FileName)
End Try
End Sub
Sub UpdateCheck()
' Checks share txt file for update.
Dim FileName As String = "C:\Users\<Me>\Documents\TestDoc.txt"
Dim FieldString() As String
'Read the file
If Not FileParser.EndOfData Then
FieldString = FileParser.ReadFields()
' 1st Field
NIS1TextBox.Text = FieldString(0)
' 2nd Field
NIS2TextBox.Text = FieldString(1)
' You get the idea...All Testboxes identified above in the write section
' Repeats 12 more times...
EODTextBox.Text = FieldString(14)
InfoRichTextBox.Text = FieldString.LastOrDefault()
End If
End Sub
Sub PushUpdate()
End Sub
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
'DefineTextFieldParse_Load()_Load() ' When Enabled code works fine when commented out generates alert.
UpdateCheck()
End Sub
End Class
mchihinney - I did review https://msdn.microsoft.com/en-us/library/hks5e2k6.aspx
However what I found was the issue was with the formatting of the text file. The problem I found was with the text file there was a second line which was blank, so when it tried to parse nothing it through the error. Deleting the second line from the .txt file and worked as expected.

Equals Not Working VB.Net

I am trying to compare two strings that I know are equal to each other, but it is always skipping to the else. I've tried everything, .Equals, =, IsNot, they all don't work! The frustrating part is that I know the strings are equal! Please take a look at my code and see if it there is possible anything wrong with it.
Public Class Form1
Dim log As String
WithEvents xworker As New System.ComponentModel.BackgroundWorker
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
xworker.RunWorkerAsync()
End Sub
Private Sub xWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles xworker.DoWork
Dim qWorker = CType(sender, System.ComponentModel.BackgroundWorker)
Dim client As New Net.WebClient
log = client.DownloadString("http://########/log.txt")
End Sub
Private Sub xWorker_Completed(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles xworker.RunWorkerCompleted
If log.Equals(RichTextBox1.Text) Then
xworker.RunWorkerAsync()
Else
RichTextBox1.Text = log
xworker.RunWorkerAsync()
End If
End Sub
End Class
You needed to listen to #SLaks and #Hans Passant, they were right on the money.
I setup your code sample and it worked correctly if the source log.txt file didn't have a line terminator in it. Once I added the line terminator I got the results your are getting.
From the command window:
>? RichTextBox1.Text.Length
14
>? log.length
15
Using the QuickWatch window, and TABing until the Value field was selected:
Log result:
"log test 1234" & vbCrLf & ""
RichTextBox result:
"log test 1234" & vbLf & ""
The fix to the problem depends on what will actually get written to the log.txt file. I assume that "log test 1234" is just development code. If you are only interested in a single line as a result code then make sure you are not writing a line terminator. If your result codes are more complicated then you will need to do more parsing on the result than just an Equals compare.
Try this instead.
If log.ToLower().Trim() = RichTextBox1.Text.ToLower().Trim() Then
I think this is case sensitve compare. You should convert both of the strings to upper or to lower and then compare them
If Log.ToLower() = RichTextBox1.Text.ToLower() Then
Or you can use String.Compare method and set third param to true to ignore case
If String.Compare(log, RichTextBox1.Text, True) = 0 Then
I've read that the RichTextBox can change line endings when Text gets set. So the Text property might be returning a string that is different than what was set. I haven't been able to verify, but you can probably devise a quick test of this theory.

File not being written to in vb.net

I did some google searching and everyone gives me the same answer which isn't working. I hope its something simple I am missing. I am trying to test write a line to a txt file. The file was created just fine when I used similar code, and no errors are thrown, the txt just doesn't write/save to the file. I am using stream writer in VB.
Here is my code:
Imports System.IO
Public Class Form1
Private Sub btnGen2DArray_Click(sender As Object, e As EventArgs)
Handles btnGen2DArray.Click
Try
'this is the file created and where it is saved:
Dim fileLoc As String = "c:\Users\clint\save.txt"
If File.Exists(fileLoc) Then
Using sw As New StreamWriter(fileLoc)
sw.Write("Test line write")
sw.Close()
End Using
End If
MsgBox("C++ 2D array text file created in: " + fileLoc, MsgBoxStyle.OkOnly, "Successful")
Catch ex As Exception
MsgBox("error: " + e.ToString(), MsgBoxStyle.OkOnly, "Error")
End Try
End Sub
Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
Close()
End Sub
End Class
I am using vb 2012 if this helps. Normal windows form application.
You need to close your StreamWriter when you are done. sw.Close
You must call Close to ensure that all data is correctly written out
to the underlying stream.
Better yet, use Using. The following would go inside your if:
Using sw As New StreamWriter(fileLoc)
sw.Write("Test line write")
For rowcount As Double = 1 To rows
For colcount As Double = 1 To cols
'when the file write test works I will finish the rest of the code here
Next
Next
End Using
This will automatically dispose of the StreamWriter for you.

Pressing a button in visual basic

I am new to Visual Basic.NET and I am just playing around with it. I have a book that tells me how to read from a file but not how to write to the file with a button click. All I have is a button and a textbox named fullNameBox. When I click the button it gives me an unhandled exception error. Here is my code:
Public Class Form1
Sub outputFile()
Dim oWrite As System.IO.StreamWriter
oWrite = System.IO.File.CreateText("C:\sample.txt")
oWrite.WriteLine(fullNameBox.Text)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
outputFile()
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
End Class
Have you tried stepping through your application to see where the error is? With a quick glance, it looks like you might need to use System.IO.File on the fourth line (oWrite = IO.File...) instead of just IO, but I haven't tried to run it.
Imports System.IO
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
SaveFileDialog1.FileName = ""
SaveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
SaveFileDialog1.ShowDialog()
If SaveFileDialog1.FileName.Trim.Length <> 0 Then
Dim fs As New FileStream(SaveFileDialog1.FileName.Trim, FileMode.Create)
Dim sr As New StreamWriter(fs)
sr.Write(TextBox1.Text)
fs.Flush()
sr.Close()
fs.Close()
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
OpenFileDialog1.FileName = ""
OpenFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
OpenFileDialog1.ShowDialog()
If OpenFileDialog1.FileName.Trim.Length <> 0 Then
Dim fs As New FileStream(OpenFileDialog1.FileName.Trim, FileMode.Open)
Dim sw As New StreamReader(fs)
TextBox1.Text = sw.ReadToEnd
fs.Flush()
sw.Close()
fs.Close()
End If
End Sub
End Class
this is a complete functional program if you want, you just need to drag drop a textbox, openfiledialog, and a savefiledialog.
feel free to play around with the code.
enjoy
by the way, the problem in your code is that you "must" close filestream when your done using it, doing so will release any resource such as sockets and file handles.
The .net framework is a very powerful framework. In the same way (however) it has easy and convenient methods for simple tasks. Most individuals tend to complicate things in order to display knowledge. But less code = less processing = faster and more efficient application (sometimes) so the large above method may not be suitable. Along with that, the above mentioned method would be better off written as a sub or if returning something then a function.
My.Computer.FileSystem.WriteAllText("File As String", "TextAsString", Append as Boolean)
A general Example would be
My.Computer.FileSystem.WriteAllText("C:\text.text", "this is what I would like to add", False)
this is what I would like to add
can be changed to the current text of a field as well.
so a more specific example would be
My.Computer.FileSystem.WriteAllText("C:\text.text", fullNameBox.text, True)
If you would like to understand the append part of the code
By setting append = true you are allowing your application to write the text at the end of file, leaving the rest of the text already in the file intact.
By setting append = false you will be removing and replacing all the text in the existing file with the new text
If you don't feel like writing that part of the code (though it is small) you could create a sub to handle it, however that method would be slightly different, just for etiquette. functionality would remain similar. (Using StreamWriter)
Private Sub WriteText()
Dim objWriter As New System.IO.StreamWriter("file.txt", append as boolean)
objWriter.WriteLine(textboxname.Text)
objWriter.Close()
End Sub
The Specific Example would be
Private Sub WriteText()
Dim objWriter As New System.IO.StreamWriter("file.txt", False)
objWriter.WriteLine(fullnamebox.Text)
objWriter.Close()
End Sub
then under the button_click event call:
writetext()
You can take this a step further as well. If you would like to create a more advabced Sub to handle any textbox and file.
Lets say you plan on having multiple separate files and multiple fields for each file (though there is a MUCH cleaner more elegant method) you could create a function. {i'll explain the concept behind the function as thoroughly as possible for this example}
below is a more advanced sub demonstration for your above request
Private Sub WriteText(Filename As String, app As Boolean, text As String)
Dim objWriter As New System.IO.StreamWriter(Filename, app)
objWriter.WriteLine(text)
objWriter.Close()
End Sub
What this does is allows us to (on the same form - if you need it global we can discuss that another time, it's not much more complex at all) call the function and input the information as needed.
Sub Use -> General Sample
WriteText(Filename As String, app As Boolean)
Sub Use -> Specific Sample
WriteText("C:\text.txt, False, fullnamebox.text)
But the best part about this method is you can change that to be anything as you need it.
Let's say you have Two Buttons* and **Two Boxes you can have the button_event for the first button trigger the above code and the second button trigger a different code.
Example
WriteText("C:\text2.txt, False, halfnamebox.text)
The best part about creating your own functions and subs are Control I won't get into it, because it will be off topic, but you could check to be sure the textbox has text first before writing the file. This will protect the files integrity.
Hope this helps!
Richard Sites.