Setting File read pointer at the beginning - vb.net

Consider the following code below in which for each entry in key.txt I add it to each line in plain.txt and write it to the output.txt.
Dim srKeyFile As New StreamReader("D:\Test\key.txt")
Dim srOutFile As New StreamWriter("D:\TestBial\output.txt")
Dim strKey, strPlain As String
While srKeyFile.Peek() >= 0
Dim srPlainFile As New StreamReader("D:\TestB\plain.txt")
strKey = srKeyFile.ReadLine()
Dim key As Integer = Integer.Parse(strKey)
While srPlainFile.Peek() >= 0
strPlain = srPlainFile.ReadLine()
Dim plain As Integer = Integer.Parse(strPlain)
srOutFile.WriteLine("" + (key + plain).ToString())
End While
srPlainFile.Close()
End While
srOutFile.Close()
Above I have to open and close the inner file on each iteration of the outer loop.Is there some way That I could position my pointer to beginning,each time I enter the inner loop for the file plain.txt

You can use StreamReader's BaseStream.Seek to do this, but you need to call DiscardBufferedData first:
srPlainFile.DiscardBufferedData()
srPlainFile.BaseStream.Seek(0, SeekOrigin.Begin)

Related

VB.net Read Specific Lines From a Text File That Start With and Stop Reading When Start With

I'm looking to read lines from a text file that start with certain characters and stop when the line starts with other characters. So in my example I would like to start reading at line AB and stop at line EF however not all lines will contain the CD line. There will always be a AB line and EF line, however the number of lines in between is unknown.
Here is an example of the lines in a text file I would be reading. You can see that this will create two rows in the DataGridView however the first row is missing the CD line and should be blank.
AB-id1
EF-address1
AB-id2
CD-name1
EF-address2
Here is the code I have so far:
Dim lines() As String = File.ReadAllLines(textfile)
For i As Integer = 0 To lines.Length - 1
If lines(i).StartsWith("AB") Then
Dim nextLines As String() = lines.Skip(i + 1).ToArray
Dim info As String = nextLines.FirstOrDefault(Function(Line) Line.StartsWith("CD"))
Dim name As String = "Yes"
Dim info2 As String = nextLines.FirstOrDefault(Function(Line) Line.StartsWith("EF"))
Dim address As String = "Yes"
End If
DataGridView.Rows.Add(name,address)
Next
Now the output I currently get is:
|Yes|Yes|
|Yes|Yes|
And I should be getting:
||Yes|
|Yes|Yes|
It looks like it's reading too far down the text file and I need it to stop reading at EF. I've tried Do while and Do Until with no success. Any suggestions?
You could use the Array.FindIndex function to get the index of the next line starting with your prefix. This way you don't have to skip lines and create a new array each time.
Try this out instead:
Dim lines() As String = File.ReadAllLines(textFile)
For i As Integer = 0 To lines.Length - 1
If lines(i).StartsWith("AB") Then
Dim addressIndex As Integer = Array.FindIndex(lines, i + 1, Function(Line) Line.StartsWith("EF"))
Dim address As String = If(addressIndex <> -1, lines(addressIndex).Substring(3), "") ' Get everything past the "-"
Dim name As String = ""
If addressIndex <> -1 Then
Dim nameIndex As Integer = Array.FindIndex(lines, i + 1, addressIndex - i, Function(line) line.StartsWith("CD"))
If nameIndex <> -1 Then
name = lines(nameIndex).Substring(3) ' Get everything past the "-"
End If
End If
DataGridView.Rows.Add(name, address)
End If
Next

Array Out of bounds error VB

Sorry for the terrible wording on my last question, I was half asleep and it was midnight. This time I'll try to be more clear.
I'm currently writing some code for a mini barcode scanner and stock manager program. I've got the input and everything sorted out, but there is a problem with my arrays.
I'm currently trying to extract the contents of the stock file and sort them out into product tables.
This is my current code for getting the data:
Using fs As StreamReader = New StreamReader("The File Path (Is private)")
Dim line As String = "ERROR"
line = fs.ReadLine()
While line <> Nothing
Dim pos As Integer = 0
Dim split(3) As String
pos = products.Length
split = line.Split("|")
productCodes(productCodes.Length) = split(0)
products(products.Length, 0) = split(1)
products(products.Length, 1) = split(2)
products(products.Length, 2) = split(3)
line = fs.ReadLine()
End While
End Using
I have made sure that the file path does, in fact, go to the file. I have looked through debug to find that all the data is going through into my "split" table. The error throws as soon as I start trying to transfer the data.
This is where I declare the two tables being used:
Dim productCodes() As String = {}
Dim products(,) As Object = {}
Can somebody please explain why this is happening?
Thanks in advance
~Hydro
By declaring the arrays like you did:
Dim productCodes() As String = {}
Dim products(,) As Object = {}
You are assigning size 0 to all your arrays, so during your loop, it will eventually try to access a position that haven't been previously declared to the compiler. It is the same as declaring an array of size 10 Dim MyArray(10) and try to access the position 11 MyArray(11) = something.
You should either declare it with a proper size, or redim it during execution time:
Dim productCodes(10) As String
or
Dim productCodes() As String
Dim Products(,) As String
Dim Position as integer = 0
'code here
While line <> Nothing
Redim Preserve productCodes(Position)
Redim Preserve products(2,Position)
Dim split(3) As String
pos = products.Length
split = line.Split("|")
productCodes(Position) = split(0)
products(0,Position) = split(1)
products(1,Position) = split(2)
products(2,Position) = split(3)
line = fs.ReadLine()
Position+=1
End While

How to create a csv file from a formatted text file

I have a text file with hundreds of prospects that I'm trying to convert to csv for importing.
Format for whole document.
Prospect Name
Description
Website
Prospect Name
Description
Website
How would I write a vb program to loop through this to make a csv file. Every 4 lines is a new prospect.
Get your file contents as an IEnumerable(of String), and spin through it, adding a CSV row for every record (into a new list(of String)). Finally write the file contents. You'll probably want to add a header row.
Dim lstLines As IEnumerable(Of String) = IO.File.ReadLines("C:\test\ConvertToCSV.txt")
Dim lstNewLines As New List(Of String)
Dim intRecordTracker As Integer = 0
Dim strCSVRow As String = String.Empty
For Each strLine As String In lstLines
If intRecordTracker = 4 Then
intRecordTracker = 0
'Trim off extra comma.
lstNewLines.Add(strCSVRow.Substring(0, (strCSVRow.Length - 1)))
strCSVRow = String.Empty
End If
strCSVRow += strLine & ","
intRecordTracker += 1
Next
'Add the last record.
lstNewLines.Add(strCSVRow.Substring(0, (strCSVRow.Length - 1)))
'Finally write the CSV file.
IO.File.WriteAllLines("C:\Test\ConvertedCSV.csv", lstNewLines)
Dim count As Integer = -1, lstOutput As New List(Of String)
lstOutput.AddRange(From b In File.ReadAllLines("C:\temp\intput.txt").ToList.GroupBy(Function(x) (Math.Max(Threading.Interlocked.Increment(count), count - 1) \ 4)).ToList() Select String.Join(",", b))
File.WriteAllLines("c:\temp\test\output.txt", lstOutput)

Change just one line in a text file?

I have a text file with the format:
(title,price,id#)
CD1,11.00,111111
CD2,12.00,222222
CD3,13.00,333333
CD4,14.00,444444
CD5,15.00,555555
CD6,16.00,666666
What is the best way to go change the price of the appropriate CD if I'm given the id# and new price?
I'm sure it has something do to with getting the line and splitting it, but I'm not sure how I edit just one line and not mess up the whole file.
You can't rewrite a line without rewriting the entire file (unless the lines happen to be the same length). For such a small file it's probably the easiest to change the line in memory and then rewrite all to the file:
Dim idToFind = "444444"
Dim newPrice = "100"
Dim lines = IO.File.ReadAllLines(path)
For i = 0 To lines.Length - 1
Dim line = lines(i)
Dim fields = line.Split(","c)
If fields.Length > 2 Then
Dim id = fields(2)
If id = idToFind Then
Dim title = fields(0)
lines(i) = String.Format("{0},{1},{2}", title, newPrice, id)
Exit For
End If
End If
Next
IO.File.WriteAllLInes(path, lines)
Okay, now we know it's a short file, life becomes much easier:
Load the file into an array of lines using File.ReadAllLines
Find the right line using string.Split to split each line into the constituent parts, and check the ID.
When you've found the right line, replace it with the complete new line
Write the file back with File.WriteAllLines
That should be enough to get you going.
If its just a file with like 25 lines, you could do a simple input-transform-output routine and update the price per line.
Something like this (Using Streamreader / writer ).
Sub UpdatePrice(ByVal pricesToUpdate As Dictionary(Of Integer, String), ByVal inputPath As String)
If Not IO.File.Exists(inputPath) Then Return
Try
Using inputStream = New IO.StreamReader(inputPath, System.Text.Encoding.UTF8, True)
Using outputStream = New IO.StreamWriter(inputPath + ".tmp", False, System.Text.Encoding.UTF8)
While Not inputStream.EndOfStream
Dim inputLine = inputStream.ReadLine
Dim content = inputLine.Split(","c)
If Not content.Length >= 3 Then
outputStream.WriteLine(inputLine)
Continue While
End If
Dim id As Integer
If Not Integer.TryParse(content(2), id) Then
outputStream.WriteLine(inputLine)
Continue While
End If
If Not pricesToUpdate.ContainsKey(id) Then
outputStream.WriteLine(inputLine)
Continue While
End If
content(1) = pricesToUpdate(id)
outputStream.WriteLine(String.Join(",", {content(0), content(1), content(2)}))
End While
End Using
End Using
If IO.File.Exists(inputPath + ".tmp") Then
IO.File.Delete(inputPath)
IO.File.Move(inputPath + ".tmp", inputPath)
End If
Catch ex As IO.IOException
If IO.File.Exists(inputPath + ".tmp") Then IO.File.Delete(inputPath + ".tmp")
End Try
End Sub

Reading line count using VB.NET

How to calculate the number of rows in a file which we have uploaded. The file might be either a text file or a CSV or Excel file.
I'm using the folowing code to get the record count like this:
Dim FileCount = From lin1 As String In File.ReadAllLines(hidFilePath.Value.ToString())
Let dd = lin1.Count
Select dd
Dim file_count As Integer = FileCount.Count
but in some cases the count is wrong.
ReadAllLines returns a string array, so you can simply take the length of the array.
Dim file_count As Integer = _
File.ReadAllLines(hidFilePath.Value.ToString()).Length
EDIT: read question to fast and answered with a loop solution
You can set your linecount as an integer and have the reader read to the end of the file.
Dim sr As New StreamReader("file path here")
Dim lineCount As Integer = System.Text.RegularExpressions.Regex.Split(sr.ReadToEnd(), Environment.NewLine).Length
sr.Close()
You can use a count variable and loop through the file until theres nothing
''name count and set it to 0
Dim count As Integer
count = 0
Dim obj As StreamReader
obj = New StreamReader("C:\...\source.txt")
''loop through the file until the end
Do Until obj.ReadLine Is Nothing
count = count + 1
Loop
''close file and show count
obj.Close()
MessageBox.Show(count)