VB can't string to arraylist when read from file - vb.net

Either I'm missing something really obvious or something about vb is really messed up. I'm trying to read in from a file and add the lines to an arraylist... pretty simple If I add strings to the arraylist this way
selectOptions.Add("Standard")
selectOptions.Add("Priority")
selectOptions.Add("3-Day")
selectOptions.Add("Overnight")
I have no problems
But when I do this it appears to end up empty which makes no sense to me.
Dim reader As StreamReader = My.Computer.FileSystem.OpenTextFileReader(path)
Dim line As String
Do
line = reader.ReadLine
selectOptions.Add(line)
Loop Until line Is Nothing
reader.Close()
Messagebox.show line all day so I know it is reading the file and the file isn't empty and I have checked the type of line which comes back as string. This makes no sense to me.

Checking for reader.EndOfStream in a While loop will probably work better:
Dim reader As New StreamReader(path)
Dim line As String
While Not reader.EndOfStream
line = reader.ReadLine
selectOptions.Add(line)
End While
reader.Close()
You can also get an exception if selectOptions isn't declared as a New ArrayList, if you properly have all your Options turned On.
Another thing to remember, if your code is in the form's Load Handler, it won't throw an exception it will just break out of the handler routine and load the form. This makes it really hard to find things like bad file names, badly declared objects, etc.
One thing I do is put suspect code in a button's Click handler and see what exceptions it throws there.
Of course this could all be moot if you use the File.ReadAllLines method and add it directly to the ArrayList:
selectOptions.AddRange(File.ReadAllLines(path))

Related

IsNothing showing error VB.NET VS2017 Community

My first post here and really basic question as I have just started learning.
I am following a step by step tutorial from youtube. https://www.youtube.com/watch?v=6utWyl8agDY code is working alright in the video. below is the code:
Imports System
Imports System.IO
Module Program
Sub Main()
Dim myReader As StreamReader = New StreamReader("values.txt")
Dim line As String = ""
While Not IsNothing(line)
line = myReader.ReadLine()
If Not IsNothing(line) Then
Console.WriteLine(line)
End If
End While
myReader.Close()
Console.ReadLine()
End Sub
End Module
Problem I am facing is that I have red error (squiggly) line under IsNothing. One thing to note is the in the video tutorial version of VS under use is 2013 while I am using VS2017 community. any idea what I am doing wrong here?
I'm not sure what your tutorial says but there are issues with that code. It's fairly poorly structured and, to be honest, you shouldn't really use IsNothing anyway. The most immediate issue is where you're reading the text and that you're testing for Nothing twice. The code would be better written like this:
Dim myReader As New StreamReader("values.txt")
Dim line As String = myReader.ReadLine()
While line IsNot Nothing
Console.WriteLine(line)
line = myReader.ReadLine()
End While
myReader.Close()
Console.ReadLine()
Comparing directly to Nothing using Is or IsNot is the way to go and there's also no need for that check inside the loop.
If you want to get a bit more advanced, you can also create the StreamReader with a Using statement, so it gets closed implicitly:
Using myReader As New StreamReader("values.txt")
Dim line As String = myReader.ReadLine()
While line IsNot Nothing
Console.WriteLine(line)
line = myReader.ReadLine()
End While
End Using
Console.ReadLine()
Better still would be to not create the StreamReader yourself at all but let the Framework do that for you:
For Each line As String In File.ReadLines("values.txt")
Console.WriteLine(line)
End Using
Console.ReadLine()
Note that that code uses ReadLines rather than ReadAllLines. Both would work but the former will only read one line at a time while the latter will read the whole file first, load the lines into an array and return that. In this case it probably doesn't really matter which you use but ReadLines is generally preferable unless you specifically need all the lines first or you want to loop over them multiple times.
You have to decide whether your console application requires .net Core or .net Framework is sufficient.
As others have written in responses, your code is in need of improvement.
However, your code will run correctly if you choose the .net framework for your new project in Visual Studio 2017 Community as shown in the screenshot below.

VB.net Reading a text file twice (Best practice - to close then re-open? Alternative?)

I am writing an assembler for a self taught course I am doing.
I have a text file I read in to a dictionary structure.
I then need to reread the same text file, but obviously I am already at the end of that file.
How do I reset to the beginning again? What is the best practice?
Thank you.
You can utilize the BaseStream property to get access to the underlying stream (when reading a local file, this will be a FileStream), then reset the stream's Position property to rewind it to the beginning.
Dim Reader As New StreamReader("somefile.txt")
Dim Contents As String = Reader.ReadToEnd()
Reader.BaseStream.Position = 0
Dim FirstLine As String = Reader.ReadLine()

how to search and display specific line from a text file vb.net

Hi I am trying to search for a line which contains whats the user inputs in a text box and display the whole line. My code below doesnt display a messsagebox after the button has been clicked and i am not sure if the record has been found
Dim filename, sr As String
filename = My.Application.Info.DirectoryPath + "\" + "mul.txt"
Dim file As String()
Dim i As Integer = 0
file = IO.File.ReadAllLines(filename)
Dim found As Boolean
Dim linecontain As Char
sr = txtsr.ToString
For Each line As String In file
If line.Contains(sr) Then
found = True
Exit For
End If
i += 1
If found = True Then
MsgBox(line(i))
End If
Next
End Sub
You should be calling ReadLines here rather than ReadAllLines. The difference is that ReadAllLines reads the entire file contents into an array first, before you can start processing any of it, while ReadLines doesn't read a line until you have processed the previous one. ReadAllLines is good if you want random access to the whole file or you want to process the data multiple times. ReadLines is good if you want to stop processing data when a line satisfies some criterion. If you're looking for a line that contains some text and you have a file with one million lines where the first line matches, ReadAllLines would read all one millions lines whereas ReadLines would only read the first.
So, here's how you display the first line that contains specific text:
For Each line In File.ReadLines(filePath)
If line.Contains(substring) Then
MessageBox.Show(line)
Exit For
End If
Next
With regards to your original code, your use of i makes no sense. You seem to be using i as a line counter but there's no point because you're using a For Each loop so line contains the line. If you already have the line, why would you need to get the line by index? Also, when you try to display the message, you are using i to index line, which means that you're going to get a single character from the line rather than a single line from the array. If the index of the line is greater than the number of characters in the line then that is going to throw an IndexOutOfRangeException, which I'm guessing is what's happening to you.
This is what comes from writing code without knowing what it actually has to do first. If you had written out an algorithm before writing the code, it would have been obvious that the code didn't implement the algorithm. If you have no algorithm though, you have nothing to compare your code to to make sure that it makes sense.

StringBuilder in .net not writing entire file

I'm trying to write a text file. Here's my main,slightly clipped for clarity:
Private Sub WriteProperty(FilePath As String)
Try
SB = New StringBuilder
WriteConfig()
'a bunch of methods similar to WriteConfig here...
Dim File As New System.IO.StreamWriter(FilePath)
File.WriteLine(SB.ToString())
Catch ex As Exception
Dim X As Integer = 5 'cheesy way to add a breakpoint
End Try
End Sub
And here is one of about a dozen subs that add text to the file:
Private Sub WriteConfig()
Dim TempSB As New StringBuilder
TempSB.AppendLine("[CONFIG]")
TempSB.AppendLine("[END_CONFIG]")
TempSB.AppendLine("")
SB.Append(TempSB)
End Sub
There are about a dozen methods that add things like this, most of them add about 2k of text instead of the couple of lines in this example. When I examine SB in the debugger the total result is a little over 15k long. But when I open the file, it's 12k, and the end is all missing - it cuts off in the middle of one of the strings. There is no exception raised.
I know SB has problems with lots of little appends, which is why I used the TempSB's in the subs, but it has the exact same problem, and if I add them directly to SB instead the only difference is the "break" occurs a few characters earlier.
Can anyone offer a suggestion as to what might be happening?
StreamWriter uses an internal buffer. You need to Close() your StreamWriter to force it to write the remaining buffered data to the file. Better yet, wrap it in a Using statement. That will call its Dispose(), which in turn calls its Close().
Using File As New System.IO.StreamWriter(FilePath)
File.WriteLine(SB.ToString())
End Using
There's a convenience method that will do this for you in a single line:
System.IO.File.WriteAllText(FilePath, SB.ToString())

Using streamreader I can read the next line of words, but can I read the previous one?

Can I read the previous line using StreamReader?
Dim previousfile As New StreamReader("file.txt")
If previousfile.Peek <> +1 Then
txtName.text = previousfile.ReadLine
End If
Can anyone help?
you cannot read the previous line - StreamReader really is a forward only type of reader. when you read a line... thats it. you cannot go back.
why dont you hold the previous line being read in a temp variable or maybe use the FileStream which has a Seek method which maybe of some use to you?
or why not read the entire contents into a collection of strings and splitting it on some delimeter for example?
You can't read backwards with a StreamReader, but if you read all of the lines in first you can traverse them however you like. This does mean reading the whole file in up front, which may be less efficient depending on your usage, but this method would do the job and give you an array:
var lines = File.ReadAllLines("file.txt")