How to read a specific line from a text file in VB - vb.net

I am creating a program that is supposed to write text into a text file, and should be able to read specific lines from a text file in VB (so if i needed to read a specific name I could select line 5 and it would display in the textbox). I am able to read the text from the text file but I do not know how to control a specific line.
Here is my code:
Public Class Form1
Private Sub btnSubmit_Click(sender As System.Object, e As System.EventArgs) Handles btnSubmit.Click
Dim writer As New System.IO.StreamWriter("/text.txt", True)
writer.WriteLine(txtFirstName.Text)
writer.WriteLine(txtLastName.Text)
writer.WriteLine("-------------------------------------")
writer.Close()
End Sub
Private Sub btnRead_Click(sender As System.Object, e As System.EventArgs) Handles btnRead.Click
Dim reader As New System.IO.StreamReader("/text.txt")
Dim FirstName, LastName As String
FirstName = reader.ReadLine()
LastName = reader.ReadLine()
reader.Close()
txtFirstName.Text = FirstName
txtLastName.Text = LastName
End Sub
Private Sub btnClear_Click(sender As System.Object, e As System.EventArgs) Handles btnClear.Click
txtFirstName.Clear()
txtLastName.Clear()
End Sub
End Class
Any help would be appreciated. Thanks!

You will have to read all lines up to the one you're interested in. For example:
Function ReadLineWithNumberFrom(filePath As String, ByVal lineNumber As Integer) As String
Using file As New StreamReader(filePath)
' Skip all preceding lines: '
For i As Integer = 1 To lineNumber - 1
If file.ReadLine() Is Nothing Then
Throw New ArgumentOutOfRangeException("lineNumber")
End If
Next
' Attempt to read the line you're interested in: '
Dim line As String = file.ReadLine()
If line Is Nothing Then
Throw New ArgumentOutOfRangeException("lineNumber")
End If
' Succeded!
Return line
End Using
End Function
This is because lines of text are variable-length records, and there is no way to guess the exact file offset where a specific line begins — not without an index.
If you frequently need to load a specific line, you have some more options:
Load the complete text file into memory, e.g. by using File.ReadAllLines("Foobar.txt"). This returns a String() array which you can access by line number directly.
Create a line number index manually. That is, process a text file line by line, and fill a Dictionary(Of Integer, Integer) as you go. The keys are line numbers, and the values are file offsets. This allows you to .Seek right to the beginning of a specific line without having to keep the whole file in memory.

Try this:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim reader As New System.IO.StreamReader("C:\text.txt")
Dim allLines As List(Of String) = New List(Of String)
Do While Not reader.EndOfStream
allLines.Add(reader.ReadLine())
Loop
reader.Close()
txtFirstName.Text = ReadLine(5, allLines)
txtLastName.Text = ReadLine(6, allLines)
End Sub
Public Function ReadLine(lineNumber As Integer, lines As List(Of String)) As String
Return lines(lineNumber - 1)
End Function
If you had a file with this:
Line 1
Line 2
Line 3
Line 4
My Name
My LastName
your name textbox will have 'My Name' and your LastName textbox will have 'My LastName'.

This is very simple, try this:
Dim strLineText As String
Dim intLineNumber As Integer
LineNumber=3
myLine = File.ReadAllLines("D:\text.txt").ElementAt(LineNumber).ToString

Yet another option
Private Function readNthLine(fileAndPath As String, lineNumber As Integer) As String
Dim nthLine As String = Nothing
Dim n As Integer
Try
Using sr As StreamReader = New StreamReader(fileAndPath)
n = 0
Do While (sr.Peek() >= 0) And (n < lineNumber)
sr.ReadLine()
n += 1
Loop
If sr.Peek() >= 0 Then
nthLine = sr.ReadLine()
End If
End Using
Catch ex As Exception
Throw
End Try
Return nthLine
End Function

i tried this and it works fine. using VB Express
content inside test.txt:
line1
line2
1
John
then in the form i add
textbox1
textbox2
label1
label2
and a button.
code inside the button:
Private Sub Button2_Click_1(sender As Object, e As EventArgs) Handles Button2.Click
Dim myLine As String
Dim lineNumber0 As Integer
lineNumber0 = 0
Dim lineNumber1 As Integer
lineNumber1 = 1
Dim lineNumber2 As Integer
lineNumber2 = 2
Dim lineNumber3 As Integer
lineNumber3 = 3
TextBox1.Text=File.ReadAllLines("D:\test.txt").ElementAt(lineNumber0).ToString
TextBox2.Text=File.ReadAllLines("D:\test.txt").ElementAt(lineNumber1).ToString
Label1.Text = File.ReadAllLines("D:\test.txt").ElementAt(lineNumber2).ToString
Label2.Text = File.ReadAllLines("D:\test.txt").ElementAt(lineNumber3).ToString
End Sub

Here's a simple but effective solution:
Dim Reader As String = System.IO.File.ReadAllLines("C:\File.txt")(1)
MsgBox("Line 1: " + Reader)
The MsgBox should show the first line of C:\File.txt.

Related

Search through text file and return a line of text

I am trying to create a program that will search a text file for a line of text and then return the full line of information.
Example line: Joe Blogs JBL 1234
Search: Joe Blogs
Search returns: Joe Blogs JBL 1234
To make it as simple as possible, I have 2 text boxes & 1 button.
Textbox1 = search
Textbox2 = Search results
Button = Search button
Can anyone tell me how to do this because I'm finding it really difficult. I'm new to VB coding so the simplest of code would be helpful!
This is what I have so far:
Imports System.IO
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Input Text Error
If TextBox1.TextLength = 0 Then
MsgBox("Please enter a Staff Name or Staff Code", MsgBoxStyle.Information, "Error")
End If
'Perform Search
Dim strText As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", TextBox1.Text)
If strText <> String.Empty Then
TextBox2.Text = strText
End If
End Sub
'Search Function
Public Shared Function SearchFile(ByVal strFilePath As String, ByVal strSearchTerm As String) As String
Dim sr As StreamReader = New StreamReader(strFilePath)
Dim strLine As String = String.Empty
Try
Do While sr.Peek() >= 0
strLine = String.Empty
strLine = sr.ReadLine
If strLine.Contains(strSearchTerm) Then
sr.Close()
Exit Do
End If
Loop
Return strLine
Catch ex As Exception
Return String.Empty
End Try
End Function
'Clear Button
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TextBox2.Text = ""
TextBox1.Text = ""
End Sub
' Open The text file
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Process.Start("C:\Users\kylesnelling\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt")
End Sub
End Class
Whenever I perform a search, all I get back is the last line of the text file... does anyone know why?
As Alex B has stated in comments, line If strLine.Contains("textbox1.text") should be If strLine.Contains(strSearchTerm)
Also you are not passing in the search item to the function. The below line you have passed in the string textbox1.text as a string rather than the text inside the textbox. Hence why you never find the line you are searching for and always returns the last record of your file.
Dim strText As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", "textbox1,text")
This line should be:
Dim strText As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", textbox1.text)
Also with this line Dim sr As StreamReader = New StreamReader("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt") why have you used the same path destination when you have already passed in this file location in the variable strFilePath.
line should be Dim sr As StreamReader = New StreamReader(strFilePath)
Its best to use the variables being passed into the function otherwise this function won't be very useful to other parts of code that may be referencing it or if search terms or filepaths change.
Updated from comments:
strLine.ToUpper.Contains(strSearchTerm.ToUpper) this line will make both text uppercase and the word you are searching for to uppercase, which will allow them to ignore case sensitivity, so for example, "text" can match with "Text" by both being converted to "TEXT" when used to compare.
Give this a try friend.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim searchResult As String = SearchFile("F:\Documents\Documents\Visual Studio 2015\Projects\ExtentionLocator\ExtentionLocator\Extentionlist.txt", _
"text to search for")
Me.TextBox2.Text = searchResult
End Sub
Public Shared Function SearchFile(ByVal strFilePath As String, ByVal strSearchTerm As String) As String
Dim fs As New System.IO.StreamReader(strFilePath)
Dim currentLine As String = String.Empty
Try
Dim searchResult As String = String.Empty
Do While fs.EndOfStream = False
currentLine = fs.ReadLine
If currentLine.IndexOf(strSearchTerm) > -1 Then
searchResult = currentLine
Exit Do
End If
Loop
Return searchResult
Catch ex As Exception
Return String.Empty
End Try
End Function

Read text file with delimiter

i want to read text file and from the fifth line take only the first column before (;) this my code to browse and read text :
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim OpenFile As New OpenFileDialog
OpenFile.FileName = ""
OpenFile.Filter = "Fichier Texte (*.pnp)|*.pnp"
OpenFile.ShowDialog()
Try
Dim lire As New System.IO.StreamReader(OpenFile.FileName)
RichTextBox1.Text = lire.ReadToEnd
lire.Close()
Catch ex As Exception
End Try
End Sub
End Class
help me please
You could try something like this:
Dim lineYouWantToRead As Int32 = 5
Dim fieldYouWantToRead As Int32 = 1
Dim capturedValue As String = ""
Using fileReader As New FileIO.TextFieldParser(OpenFile.FileName)
fileReader.TextFieldType = FileIO.FieldType.Delimited
fileReader.SetDelimiters(";")
While fileReader.LineNumber <= lineYouWantToRead - 1
Dim currentLine As String() = fileReader.ReadFields()
capturedValue = currentLine(fieldYouWantToRead - 1)
End While
End Using
RichTextBox1.Text = capturedValue
Let us know if that is any help.

Variables are used before it is assigned a null value. Using StreamReader

I decided to try one of the advanced exercises in my book, it needs me to edit a program. Before getting the artist name and price, the btn.Add_Click procedure should determine whether the CD name is already included in the list box. If the list box contains the CD name, the procedure should display an appropriate message and then not add the CD to the list. Problem is the Do Until inFile.Peek = -1 and the For Each Name As String In strNameCollection apparently are assigned a null value. Any ideas on why this is or possibly how to get this to work? btn.Add_Click is towards the bottom of the code
Option Explicit On
Option Strict On
Option Infer Off
Public Class frmMain
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub
Private Sub frmMain_FormClosing(sender As Object, e As Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
' save the list box information
' declare a StreamWriter variable
Dim outFile As IO.StreamWriter
' open the file for output
outFile = IO.File.CreateText("CDs.txt")
' write each line in the list box
For intIndex As Integer = 0 To lstCds.Items.Count - 1
outFile.WriteLine(lstCds.Items(intIndex))
Next intIndex
' close the file
outFile.Close()
End Sub
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles Me.Load
' fills the list box with data
' stored in a sequential access file
' declare variables
Dim inFile As IO.StreamReader
Dim strInfo As String
' verify that the file exists
If IO.File.Exists("CDs.txt") Then
' open the file for input
inFile = IO.File.OpenText("CDs.txt")
' process loop instructions until end of file
Do Until inFile.Peek = -1
strInfo = inFile.ReadLine
lstCds.Items.Add(strInfo)
Loop
inFile.Close()
' select the first line in the list box
lstCds.SelectedIndex = 0
Else
MessageBox.Show("Can't find the CDs.txt file",
"CD Collection",
MessageBoxButtons.OK,
MessageBoxIcon.Information)
End If
End Sub
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
' adds CD information to the list box
' declare variables
Dim strName As String
Dim strArtist As String
Dim strPrice As String
Dim strConcatenatedInfo As String
Dim dblPrice As Double
Dim strNameCollection() As String
'read all names into array
Dim inFile As IO.StreamReader
If IO.File.Exists("CDs.txt") Then
' open the file for input
inFile = IO.File.OpenText("CDs.txt")
End If
'read all names into array
Dim index As Integer = 0
Do Until inFile.Peek = -1
ReDim strNameCollection(index)
strNameCollection(index) = inFile.ReadLine
Loop
inFile.Close()
' get the CD information
strName = InputBox("CD name:", "CD Collection")
For Each Name As String In strNameCollection
If strName = Name Then
MessageBox.Show("Sorry that name was alread on the list", "CD Project",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
Else
strArtist = InputBox("Artist:", "CD Collection")
strPrice = InputBox("Price:", "CD Collection")
Double.TryParse(strPrice, dblPrice)
strPrice = dblPrice.ToString("N2")
strConcatenatedInfo = strName.PadRight(40) &
strArtist.PadRight(25) & strPrice.PadLeft(5)
lstCds.Items.Add(strConcatenatedInfo)
End If
Next Name
End Sub
Private Sub btnRemove_Click(sender As Object, e As EventArgs) Handles btnRemove.Click
' removes the selected line from the list box
' if a line is selected, remove the line
If lstCds.SelectedIndex <> -1 Then
lstCds.Items.RemoveAt(lstCds.SelectedIndex)
End If
End Sub
End Class
Why not take advantage of the Using blocks? Make strNameCollection a List(Of String) instead of an array that you are not increasing it's size correctly.
Private strNameCollection As New List(Of String)
Using sr As New StreamReader("CDs.txt")
While Not sr.EndOfStream
strNameCollection.Add(sr.ReadLine)
End while
End Using ' file closed and stream disposed

VB.net multithreading for loop, parallel threads

I have a simple form with 2 RichTextBoxes and 1 button, the code grabs the url address from RichTextBox1 and phrases the page for the title field using regex and appends it to RichTextBox2. I want to multithread everything in such way that none of the url's are skipped and the thread numbers can be set ( according to the system free resources ) For example, let's say 10 threads to run in parallel. I searched everything and the best that I managed to do is run everything in a background worker and keep the GUI from freezing while working. A short code sample will be of much help, I am a beginner in VB.net.
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For i = 0 To RichTextBox1.Lines.Length - 1
If RichTextBox1.Lines(i).Contains("http://") Then
Dim html As String = New System.Net.WebClient() _
.DownloadString(RichTextBox1.Lines(i))
Dim pattern As String = "(?<=\<title\>)([^<]+?)(?=\</title\>)"
Dim match As System.Text.RegularExpressions.Match = _
System.Text.RegularExpressions.Regex.Match(html, pattern)
Dim title As String = match.Value
RichTextBox2.AppendText(title & vbCrLf)
End If
Next
End Sub
End Class
Updated code ( throwing "Index was outside the bounds of the array." errors. )
Imports System
Imports System.Threading
Public Class Form1
Public Sub test(ByVal val1 As String, ByVal val2 As String)
Dim zrow As String
zrow = RichTextBox1.Lines(val1)
If zrow.Contains("http://") Then
Dim html As String = New System.Net.WebClient().DownloadString(zrow)
Dim pattern As String = "(?<=\<title\>)([^<]+?)(?=\</title\>)"
Dim match As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(html, pattern)
Dim title As String = match.Value
RichTextBox2.AppendText(val2 & title & vbCrLf)
End If
End Sub
Public Sub lastfor(ByVal number)
Dim start As Integer = number - 100
For x = start To number - 1
Try
test(x, x)
RichTextBox2.AppendText(x & RichTextBox1.Lines(x).Trim & vbCrLf)
Catch ex As Exception
'MsgBox(ex.Message)
RichTextBox3.AppendText(ex.Message & vbCrLf & vbCrLf)
End Try
Next
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Control.CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim TotalLines As String = RichTextBox1.Lines.Length - 1
Dim TotalThreads As Integer = 10
Dim LinesPerThread As Integer = TotalLines / TotalThreads
Dim increment As String = LinesPerThread
Dim zdata(TotalThreads) As String
For i = 0 To TotalThreads - 1
zdata(i) = increment
increment = increment + LinesPerThread
Next
Dim lst As New List(Of Threading.Thread)
For Each bump As String In zdata
Dim t As New Threading.Thread(Function(l As String)
'Do something with l
'Update GUI like this:
If bump = String.Empty Or bump Is Nothing Then
Else
lastfor(l)
'MsgBox(l)
End If
End Function)
lst.Add(t)
t.Start(bump)
Next
'test(1)
End Sub
End Class
There are two ways two achieve this:
First, if you are using .NET 4.0, you could use a Parallel.ForEach loop:
Parallel.ForEach(RichTextBox1.Lines, Function(line As String)
' Do something here
' To update the GUI use:
Me.Invoke(Sub()
' Update GUI like this...
End Sub)
Return Nothing
End Function)
The other way is to do this manually (and you will have slightly more control):
Dim lst As New List(Of Threading.Thread)
For Each line In RichTextBox1.Lines
Dim t As New Threading.Thread(Function(l As String)
'Do something with l
'Update GUI like this:
Me.Invoke(Sub()
'Update Gui...
End Sub)
End Function)
lst.Add(t)
t.Start(line)
Next
Both of these are very crude, but will get the job done.
EDIT:
Here is a sample code that will control the number of threads:
Dim lst As New List(Of Threading.Thread)
Dim n As Integer = 1 ' Number of threads.
Dim npl As Integer = RichTextBox1.Lines / n
Dim seg As New List(Of String)
For Each line In RichTextBox1.Lines
For i = npl - n To npl
seg.Add(RichTextBox1.Lines.Item(i))
Next
Dim t As New Threading.Thread(Function(l As String())
For Each lin In l
' TO-DO...
Next
'Do something with l
'Update GUI like this:
Me.Invoke(Sub()
'Update Gui...
End Sub)
End Function)
lst.Add(t)
t.Start(seg.ToArray())
Next
*The above code might have bugs.

Importing last line of a .csv file

I have a csv file and I need to get the last line only into seperate textboxes.
Imports System.IO
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub btnConditions_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConditions.Click
Using reader As New StreamReader("C:\temp\Apr12log.txt")
Dim line As String = reader.ReadLine()
Dim fields() As String = line.Split(",".ToCharArray())
Dim fileDate = CDate(fields(0))
Dim fileTime = fields(1)
Dim fileTemp = fields(2)
Dim fileHum = fields(3)
Dim fileWindSpeed = fields(4)
Dim fileWindGust = fields(5)
Dim fileWindBearing = fields(6)
While line IsNot Nothing
line = reader.ReadLine()
End While
txtDate.Text = CStr(fileDate)
End Using
End Sub
End Class
It only inputs the first line I am not sure how to get the last line only.
example of txtfile
01/04/12,00:00,5.4,80,3.0,4.5,9.6,261,0.0,0.0,1025.0,1.0,16.8,43,4.0,3.8,5.4,0.0,0,0.0
Alternatively, you could use the System.IO.File ReadLines() function, which gives you an enumerable that you can call Last() on.
Private Sub btnConditions_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConditions.Click
Dim line As String = System.IO.File.ReadLines("C:\temp\Apr12log.txt").Last()
Dim fields() As String = line.Split(",".ToCharArray())
Dim fileDate = CDate(fields(0))
Dim fileTime = fields(1)
Dim fileTemp = fields(2)
Dim fileHum = fields(3)
Dim fileWindSpeed = fields(4)
Dim fileWindGust = fields(5)
Dim fileWindBearing = fields(6)
txtDate.Text = CStr(fileDate)
End Sub
You're only reading in one line. Instead use ReadToEnd() and then split by a new line, like so:
Dim lines() As String = reader.ReadToEnd().Split(Environment.NewLine)
Then you can move to the last line:
Dim line As String = lines(lines.Length - 1)
You can get what you want with a couple of edits to your existing code:
Shift
While line IsNot Nothing
line = reader.ReadLine()
End While
To just after
Dim line As String = reader.ReadLine()
Add another
Dim line2 As String = Nothing
And insert
line2 = line
Into the While loop, i.e.
While line IsNot Nothing
line2 = line
line = reader.ReadLine()
End While
Now line2 is the last line in the file.
Try this:
Dim lines() As String = File.ReadAllLines("C:\temp\Apr12log.txt")
lastLine = lines(lines.Length - 1)