How to loop when using FileSystem.input? - vb.net

I'm migrating a program from vb6 to vb.net.
I have a file with multiple lines to read from.
My code:
FileOpen(1,FileName,OpenMode.Input)
Do until EOF(1)
FileSystem.Input( 1 , param1, param2, param3)
Loop
My problem with this code is that the loop isn't "looping"...
Its reading the same line over and over.
When using :
Do until FileSystem.EOF(1)
strData = Filesystem.LineInput(1)
Loop
The loop works fine.
But I can't use it because I have different params for each line, which is inconsistent.
What is the problem? Why isn't it looping for the first time?
Are there other approaches for tackling this problem?

Are there other approaches for this kind of code?
Read all the lines of a text file into an array all in memory in one go (assuming it's a text file because you said "multiple lines"):
Dim arr = System.IO.File.ReadAllLines("path here")
'loop over the array
For Each line as String in arr
'... process the line
Next line
To read a file incrementally, line by line, if it's huge and you don't want to load it all into memory, use ReadLines instead of ReadAllLines:
For Each line as String in System.IO.File.ReadLines("path here")
'... process the line
Next line

Another example:
Imports System.IO
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim line As String
Dim values() As String
Dim FileName As String = "c:\someFile.txt"
Using sr As New StreamReader(FileName)
While Not sr.EndOfStream
line = sr.ReadLine()
values = line.Split(",")
End While
End Using
End Sub
End Class
If you show us some sample lines from your file we could give more detailed answers.

Related

Writing/Reading from text files in VB.net

I am a student in computer science and for a project I need to be able to read from a text file in a way that each line is assigned to a space within an array. This should happen so that each line of text file is read in the order that it appears in the text file. I would also appreciate any methods of writing to a text file as well.
If this question is already explained, could you please direct me to the existing answer.
Things to note:
1) I am coding in a console application in VB.NET
2) I am relatively new at coding
You can do it like this:
Dim sFile As String = "D:\File.txt"
Dim aLines As String() = System.IO.File.ReadAllLines(sFile)
System.IO.File.WriteAllLines(sFile, aLines)
Here's a sample from the official documentation:
Imports System.IO
Public Class Test
Public Shared Sub Main()
Dim path As String = "c:\temp\MyTest.txt"
Dim sw As StreamWriter
' This text is added only once to the file.
If File.Exists(path) = False Then
' Create a file to write to.
Dim createText() As String = {"Hello", "And", "Welcome"}
File.WriteAllLines(path, createText)
End If
' This text is always added, making the file longer over time
' if it is not deleted.
Dim appendText As String = "This is extra text" + Environment.NewLine
File.AppendAllText(path, appendText)
' Open the file to read from.
Dim readText() As String = File.ReadAllLines(path)
Dim s As String
For Each s In readText
Console.WriteLine(s)
Next
End Sub
End Class
Remarks
This method opens a file, reads each line of the file, then adds each line as an element of a string array. It then closes the file. A line is defined as a sequence of characters followed by a carriage return ('\r'), a line feed ('\n'), or a carriage return immediately followed by a line feed. The resulting string does not contain the terminating carriage return and/or line feed.
Module Module1
Sub Main()
'Declare four variables
Dim oReader As New System.IO.StreamReader(".\archive01.txt") 'This file has to exist in the aplication current directory.
Dim oWriter As New System.IO.StreamWriter(".\archive02.txt") 'This file will be created by the software.
Dim oArray() As String = {}
Dim oString As String = Nothing
'For reading from .\archive01.txt and to load in oArray().
oString = oReader.ReadLine
While Not oString Is Nothing
If UBound(oArray) = -1 Then 'Ubound = Upper Bound, also exist LBound = Lower Bound.
ReDim oArray(UBound(oArray) + 1)
Else
ReDim Preserve oArray(UBound(oArray) + 1)
End If
oArray(UBound(oArray)) = New String(oString)
oString = oReader.ReadLine
End While
oReader.Close()
'For writing from oArray() to .\archive02.txt.
For i = 0 To oArray.Count - 1 Step 1
oWriter.WriteLine(oArray(i))
Next
oWriter.Close()
End Sub
End Module
Hi, try with this code. It works well. I hope that this helps to you to learn how to do this kind of things. Thank you very much. And happy codding!. :)

Saving a Structure to a Binary File

I am creating an application using a windows forms application in visual studio in the vb.net language. I need help converting a structure that I coded into a binary file that is essentially a save in user results. I'm not a very good coder so excuse the poor code.
The code below shows that I have created a structure called saveresults and by clicking button1, it should get the contents of the binary file and edit them to be the new result. When I run the code the problem seems to be in the line FileOpen(1, "/bin/debug/1.txt", OpenMode.Binary) in the saveres subroutine.
Structure saveresults 'Structure for saving results
Dim numright As Integer
Dim numwrong As Integer
Dim totalnum As Integer
End Structure
'Subroutine aimed at getting stats saved to a text file to eventually be displayed to the user
Sub saveres(saveresults As saveresults, correct As Boolean)
saveresults.totalnum = saveresults.totalnum + 1
'Determining the contents to be saved to the binary file
If correct = True Then
saveresults.numright = saveresults.numright + 1
ElseIf correct = False Then
saveresults.numwrong = saveresults.numwrong + 1
End If
FileOpen(1, "/bin/debug/1.txt", OpenMode.Binary)
FilePut(1, saveresults)
FileClose(1)
End Sub
'attempt at saving results to the binary file
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim correct = True
Dim results As saveresults
FileOpen(1, "/bin/debug/1.txt", OpenMode.Binary)
FileGet(1, results)
saveres(results, correct)
FileClose(1)
End Sub
Any help would be appreciated. Thank you.
Use this instead
FileOpen(1, "1.txt", OpenMode.Binary)
Using the above opens the file in your project's debug folder.
You are referring to text files and binary files as if they are the same thing. They are not. Text files are human readable in Notepad; binary files are not.
I have not used the methods you are attempting since VB 6. Use the .Net System.IO methods. To use these you need to add Imports System.IO at the very top of your code file.
I have broken your code into Subs and Functions that have a single purpose. Reading the file, writing the file, updating the data, and displaying the data. This makes code more maintainable. If your code misbehaves it is easier to find the error and easier to fix if a method has only one thing to do.
The file location in the example is in the same directory as your .exe file. Probably
/bin/Degug.
'A Form level variable to hold the data
Private results As New saveresults
Structure saveresults 'Structure for saving results
Dim numright As Integer
Dim numwrong As Integer
Dim totalnum As Integer
End Structure
'Update the data
Private Sub UpdateResults(Correct As Boolean)
'It is not necessary to include = True when testing a Boolean
If Correct Then
'this is a shortcut method of writin results.numright = results.numright + 1
results.numright += 1
'A Boolean can only be True or False so if it is not True
'it must be False so, we can just use an Else
'No need to check the condition again
Else
results.numwrong += 1
End If
results.totalnum += 1
End Sub
'Write text file
Private Sub SaveResultsFile(results As saveresults, correct As Boolean)
Dim sb As New StringBuilder
sb.AppendLine(results.numright.ToString)
sb.AppendLine(results.numwrong.ToString)
sb.AppendLine(results.totalnum.ToString)
File.WriteAllText("1.txt", sb.ToString)
End Sub
'Read the text file
Private Function ReadResultsFile() As saveresults
Dim ResultsFiLe() = File.ReadAllLines("1.txt")
Dim results As New saveresults With
{
.numright = CInt(ResultsFiLe(0)),
.numwrong = CInt(ResultsFiLe(1)),
.totalnum = CInt(ResultsFiLe(2))
}
Return results
End Function
'Display
Private Sub DisplayResults()
Dim ResultsToDisplay As saveresults = ReadResultsFile()
'The $ indicates an interpolated string, the same thing can be accomplished with String.Format
Label1.Text = $"The correct number is {ResultsToDisplay.numright}. The wrong number is {ResultsToDisplay.numwrong}. The total is {ResultsToDisplay.totalnum}."
End Sub

Writing and Reading DataGridView to text file

I'm looking for some assistance on how to populate a DataGridView control with data from a text file. The column number is static, but the row count is dynamic. I am using StreamWriter to create the text file line by line. Here is the code:
Private Sub btnSaveReport_Click(sender As Object, e As EventArgs) Handles btnSaveReport.Click
Dim path As String = "c:\users\service5\desktop\ReportFile.txt"
Using writer As New StreamWriter(path)
For row As Integer = 0 To dgvLabor.RowCount - 2
For col As Integer = 0 To dgvLabor.ColumnCount - 1
writer.WriteLine("Labor" & "|" & dgvLabor.Rows(row).Cells(col).Value)
Next
Next
writer.Close()
End Using
End Sub
The output file looks like this:
Labor|Mon 09/25/2017
Labor|Labor Time
Labor|11:42 PM
Labor|12:42 AM
Labor|23.00
Labor|20
I'm stumped when using the StreamReader method to read each line from the text file and place it in the correct column and row. I had success populating text boxes using the "|" delimited format, but I'm not sure how to go about tackling the DataGridView code. Would it be wise to reformat my StreamWriter method to make the file comma delimited instead of "|" delimited?
UPDATE 10/08/2017
Ok, I have the writer formatting the text file the way I want and the StreamReader is 95% working. It successfully populates the DataGridView for the first row, but it needs to recognize every line beginning with "Labor" and add a new row with the array in the line. Here is a sample of the text I'm trying to read into the DataGridView.
Labor,Sun 10/08/2017,Labor Time,12:39 AM,12:39 AM,0.00,0
Labor,Mon 10/09/2017,Travel Time,12:39 AM,12:39 AM,0.00,0
Here is the StreamReader code:
Private Sub OpenFileDialog1_FileOk(sender As Object, e As CancelEventArgs) Handles OpenFileDialog1.FileOk
Dim FileReader As StreamReader
Dim prop(2) As String
Dim path As String = OpenFileDialog1.FileName
FileReader = New StreamReader(path, False)
Do Until FileReader.EndOfStream
prop = FileReader.ReadLine().Split(",")
If String.Equals(prop(0), "Labor") Then
Dim col(6) As String
Dim index = dgvLabor.Rows.Add()
col = FileReader.ReadLine().Split(",")
dgvLabor.Rows(index).SetValues(col(1), col(2), col(3), col(4), col(5), col(6))
End If
Loop
FileReader.Close()
End Sub
The part I'm having trouble with is the number of lines beginning with "Labor" will vary every time the text file is written, so I think I need a Do Until or Do While loop within the If String.Equals method, but I cannot get the syntax right. I've tried these so far with no success:
Do While String.Equals("Labor")
Do Until String.Equals(Not "Labor")
Do Until String.Equals(prop(0), "Labor")
Any ideas?
UPDATE WITH SOLUTION 10/09/2017
After really thinking about what my code is doing, I finally solved the problem. It's stupid simple and proves how much I was overthinking everything. Thanks for your assistance and patience with me, jmcilhinney. Hope this can help someone else out as well.
ElseIf String.Equals(prop(0), "Labor") Then
dgvLabor.Rows.Add(prop(1), prop(2), prop(3), prop(4), prop(5), prop(6))
End If
After really thinking about what my code is doing, I finally solved the problem. It's stupid simple and proves how much I was overthinking everything. Thanks for your assistance and patience with me, jmcilhinney. Hope this can help someone else out as well.
ElseIf String.Equals(prop(0), "Labor") Then
dgvLabor.Rows.Add(prop(1), prop(2), prop(3), prop(4), prop(5), prop(6))
End If
This code takes the already split line and inserts the desired objects of the array into the next available row's cells. It only adds the lines in the text document that begin with "Labor"

Going through each line in a text-file and adding to listbox

I have a text-file (customers.txt) which I am trying to extract certain pieces of Information from. I have split up each line in the text-file using commas and in doing so allowing me to place parts of a line in a list-box(lstReportsUnresolved). However, I am having difficulties creating a loop to do this for each line in the text file, adding parts from each line to the list-box.
The code:
Private Sub btnUnresolved_Click(sender As Object, e As EventArgs) Handles btnUnresolved.Click
Dim reader As New StreamReader("customers.txt")
Dim data As String()
data = reader.ReadLine().Split(",")
If data(18) = "No" Then
lstReportsUnresolved.Items.Add(data(17))
End If
If data(20) = "No" Then
lstReportsUnresolved.Items.Add(data(19))
End If
If data(22) = "No" Then
lstReportsUnresolved.Items.Add(data(21))
End If
If data(24) = "No" Then
lstReportsUnresolved.Items.Add(data(23))
End If
End Sub
I have tried adding
For Each Line As String In File.ReadLines("customers.txt")
Next
with the if statements between them but this just seems to add the sections from the first line to the list-box three times.
I'm am new to VB so apologies if I am making a silly mistake.
Thank you for your help and time.
Have you also splitted every line in the loop?
For Each line As String In File.ReadLines("customers.txt")
Dim data As String() = line.Split(",")
If data(18) = "No" Then
lstReportsUnresolved.Items.Add(data(17))
End If
' .... '
Next
However, using , as delimiter is error-prone because the values might also contain commas.

Separating large file and inserting carriage returns based on string

New to VB.Net but a friend recommended that I used it for what I'm trying to do. I have a huge text file and I want to insert carriage returns in after a specific string.
Apart from the mess I have below , how would I alter this to read a file and then once we see the text "ext" insert a new line feed. I'm expecting one of the lines in the input file to produce alot of carriage returns.
Currently what I have managed to mock together below reads an input file until end of line and writes it out again into another file.
Module Module1
Sub Main()
Try
' Create an instance of StreamReader to read from a file.
' The using statement also closes the StreamReader.
Using sr As StreamReader = New StreamReader("C:\My Documents\input.txt")
Dim line As String
' Read and display lines from the file until the end of
' the file is reached.
Using sw As StreamWriter = New StreamWriter("C:\My Documents\output.txt")
Do Until sr.EndOfStream
line = sr.ReadLine()
sw.WriteLine(line)
Console.WriteLine("done")
Loop
End Using
End Using
Catch e As Exception
' Let the user know what went wrong.
Console.WriteLine("The file could not be read:")
Console.WriteLine(e.Message)
End Try
Console.ReadKey()
End Sub
Changes made following comments.. Falling over at 500mb files due to memory constraints:
Sub Main()
Try
' Create an instance of StreamReader to read from a file.
' The using statement also closes the StreamReader.
Using sr As StreamReader = New StreamReader("C:\My Documents\input.txt")
Dim line As String
Dim term As String = "</ext>"
' Read and display lines from the file until the end of
' the file is reached.
Using sw As StreamWriter = New StreamWriter("C:\My Documents\output.txt")
Do Until sr.EndOfStream
line = sr.ReadLine()
line = line.Replace(term, term + Environment.NewLine)
sw.WriteLine(line)
Console.WriteLine("done")
Loop
End Using
End Using
Since your lines are very big, you'll have to:
Read/Write one character at a time
Save the last x characters
If the last x characters are equal to your term, write a new line
Dim term As String = "</ext>"
Dim lastChars As String = "".PadRight(term.Length)
Using sw As StreamWriter = New StreamWriter("C:\My Documents\output.txt")
Using sr As New System.IO.StreamReader("C:\My Documents\input.txt")
While Not sr.EndOfStream
Dim buffer(1) As Char
sr.Read(buffer, 0, 1)
lastChars &= buffer(0)
lastChars = lastChars.Remove(0, 1)
sw.Write(buffer(0))
If lastChars = term Then
sw.Write(Environment.NewLine)
End If
End While
End Using
End Using
Note: This will not work with a Unicode file. This assume each characters are one byte.