last line


Read First and last line from text file

Question

    • I have a text file whose location is d:\abc\abc.txt

      I have two text boxes whose names are txtFirstLine and txtLastLine respectively

      I want to read and display the first line of the textfile in txtFirstLine textbox

      and I want to read and display the last line of the textfile in txtLastLine textbox

      How can we do this in vb.net 2010

      Any help will be appreciated.

      Thanks

      Tuesday, February 05, 2013 4:34 PM
      ConfCon Networks

      10 Points

Answers

    • You can do it like this:

      Dim lines() As String = IO.File.ReadAllLines("d:\abc\abc.txt")
      txtFirstLine.Text = lines(0)
      txtLastLine.Text = lines(lines.Length - 1)

      The code reads the text file and creates an array of Strings with one line in each element of the array.  Then it copies the first line into one TextBox and the last line into the other.  Note that there is no way to find the last line of a text file without reading the whole file in some way.If your text file is hundreds of megabytes long, you might not want to read it all into memory at the same time. That seems unlikely, but if that is the case, let us know and we can show you how to just read one line at a time.

      Tuesday, February 05, 2013 4:50 PM

      26,935 Points

    • Hi,

      No miracle solution, you’ll have to read the whole file to reach the last line.

      You could load the entire file using File.ReadAllLines and then retrieve the First and Last one (FirstOrDefault and LastOrDefault if file can be empty)

      Alternatively you could use a StreamReader (or equivalent) and loop through the file.

      examples (I assume the File exists):

      ' first method
      Dim lines As String() = File.ReadAllLines(path)
      Dim firstLine As String = lines.First ' lines.FirstOrDefault
      Dim lastLine As String = lines.Last ' lines.LastOrDefault
      
      ' second method
      Dim firstLine As String = Nothing ' or String.Empty
      Dim lastLine As String = Nothing ' same here
      
      Using reader As New StreamReader(path)
          If Not reader.EndOfStream Then firstLine = reader.ReadLine
          Do Until reader.EndOfStream
              ' replace "previous" last line with "current" read line ,
              ' hence at end of loop lastLine will contain the "real" last line.
              lastLine = reader.ReadLine
          Loop
      End Using

      Typically the second approach is better if the file are large because you don’t have to load the whole file in memory at once.

      Tuesday, February 05, 2013 4:55 PM

      845 Points

    • I could test a little (my previous post was only based on my memory)

      And I remember of File.ReadLines (requires FW 4 or later)

      It’s different of File.ReadAllLines because it evaluates lazily (it streams its data) and so can perform pretty well.

      Dim watch = Stopwatch.StartNew
      Dim lines = IO.File.ReadLines(path)
      
      Dim first = lines.FirstOrDefault
      Dim last = lines.LastOrDefault
      
      Console.WriteLine("{1}{0}{2}{0}{3}",
          Environment.NewLine, first, last, watch.Elapsed)

      With my computer for a file of approx 150 000 words (generated via Lorem Ipsum)I got a time of 7 milliseconds

      • Proposed as answer by JohnWein Tuesday, February 05, 2013 11:25 PM
      • Marked as answer by Shanks ZenModerator Friday, February 15, 2013 9:32 AM
      Tuesday, February 05, 2013 10:58 PM

      845 Points

All replies

    • You can do it like this:

      Dim lines() As String = IO.File.ReadAllLines("d:\abc\abc.txt")
      txtFirstLine.Text = lines(0)
      txtLastLine.Text = lines(lines.Length - 1)

      The code reads the text file and creates an array of Strings with one line in each element of the array.  Then it copies the first line into one TextBox and the last line into the other.  Note that there is no way to find the last line of a text file without reading the whole file in some way.If your text file is hundreds of megabytes long, you might not want to read it all into memory at the same time. That seems unlikely, but if that is the case, let us know and we can show you how to just read one line at a time.

      Tuesday, February 05, 2013 4:50 PM

      26,935 Points

    • Hi,

      No miracle solution, you’ll have to read the whole file to reach the last line.

      You could load the entire file using File.ReadAllLines and then retrieve the First and Last one (FirstOrDefault and LastOrDefault if file can be empty)

      Alternatively you could use a StreamReader (or equivalent) and loop through the file.

      examples (I assume the File exists):

      ' first method
      Dim lines As String() = File.ReadAllLines(path)
      Dim firstLine As String = lines.First ' lines.FirstOrDefault
      Dim lastLine As String = lines.Last ' lines.LastOrDefault
      
      ' second method
      Dim firstLine As String = Nothing ' or String.Empty
      Dim lastLine As String = Nothing ' same here
      
      Using reader As New StreamReader(path)
          If Not reader.EndOfStream Then firstLine = reader.ReadLine
          Do Until reader.EndOfStream
              ' replace "previous" last line with "current" read line ,
              ' hence at end of loop lastLine will contain the "real" last line.
              lastLine = reader.ReadLine
          Loop
      End Using

      Typically the second approach is better if the file are large because you don’t have to load the whole file in memory at once.

      Tuesday, February 05, 2013 4:55 PM
      Sehnsucht_Fr

      845
      Points
      Top 5
      Sehnsucht_Fr
      Joined Sep 2012

      1

      9

      845 Points

    • This will work without reading the entire file.

      Dim sr As IO.StreamReader = New IO.StreamReader(path)

      Dim fl As String = sr.ReadLine ‘first line
      Dim ll As String ‘last line
      Dim i As Integer = 2
      sr.DiscardBufferedData()
      Do
      If i <= sr.BaseStream.Length Then
      sr.BaseStream.Seek(sr.BaseStream.Length – i, IO.SeekOrigin.Begin)
      ll = sr.ReadToEnd
      If ll.StartsWith(Environment.NewLine) Then
      Exit Do
      End If
      i += 1
      Else
      Throw New Exception(“one line”)
      End If
      Loop
      ll = ll.Replace(Environment.NewLine, “”)
      sr.Close()


      “Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it.” JohnWein

      Tuesday, February 05, 2013 5:38 PM
      dbasnett

      11,791
      Points
      Top 1
      dbasnett
      Joined Apr 2007

      2

      4

      17

      State of Missouri

      11,791 Points

    • If it’s a large text file, you can do it without reading the entire file using this code:

      Dim SR As New StreamReader(File.OpenRead(“D:\abc\abc.txt”))
      txtFirstLine.Text = SR.ReadLine
      Dim LastLine As String, I, J As Integer, P As Long
      Do
      I = 0 : J += 128 : P = SR.BaseStream.Length – J
      If P < 0 Then P = 0
      SR.BaseStream.Position = P
      Do
      LastLine = SR.ReadLine : I += 1
      Loop Until SR.EndOfStream
      Loop Until I > 1 Or P = 0
      SR.Close()
      txtLastLine.Text = LastLine

      Tuesday, February 05, 2013 6:36 PM
      JohnWein

      90,015
      Points
      Top 0.1
      JohnWein
      Joined May 2008

      4

      5

      12

      Screen for lung cancer.

      90,015 Points

    • If it’s a large text file, you can do it without reading the entire file using this code:

      Dim SR As New StreamReader(File.OpenRead(“D:\abc\abc.txt”))
      txtFirstLine.Text = SR.ReadLine
      Dim LastLine As String, I, J As Integer, P As Long
      Do
      I = 0 : J += 128 : P = SR.BaseStream.Length – J
      If P < 0 Then P = 0
      SR.BaseStream.Position = P
      Do
      LastLine = SR.ReadLine : I += 1
      Loop Until SR.EndOfStream
      Loop Until I > 1 Or P = 0
      SR.Close()
      txtLastLine.Text = LastLine

      Missing an EndIf somewhere.  I am guessing that this code is taking a SWAG at line length.


      “Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it.” JohnWein

      Tuesday, February 05, 2013 8:02 PM
      dbasnett

      11,791
      Points
      Top 1
      dbasnett
      Joined Apr 2007

      2

      4

      17

      State of Missouri

      11,791 Points

    • “Missing an EndIf somewhere.”

      Don’t know where it would be.  There is only one explicit If statement in the code and it’s a single line.

      Tuesday, February 05, 2013 8:09 PM
      JohnWein

      90,015
      Points
      Top 0.1
      JohnWein
      Joined May 2008

      4

      5

      12

      Screen for lung cancer.

      90,015 Points

    • “Missing an EndIf somewhere.”

      Don’t know where it would be.  There is only one explicit If statement in the code and it’s a single line.

      I see it now.

      I tested yours and mine with a file I have that is 900 lines long, average 72 characters per line.  Mine performed better.  It has to do with the position and what is in the buffer.  I had the same issue until I added the .DiscardBufferedData.


      “Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it.” JohnWein

      Tuesday, February 05, 2013 9:55 PM
      dbasnett

      11,791
      Points
      Top 1
      dbasnett
      Joined Apr 2007

      2

      4

      17

      State of Missouri

      11,791 Points

    • I could test a little (my previous post was only based on my memory)

      And I remember of File.ReadLines (requires FW 4 or later)

      It’s different of File.ReadAllLines because it evaluates lazily (it streams its data) and so can perform pretty well.

      Dim watch = Stopwatch.StartNew
      Dim lines = IO.File.ReadLines(path)
      
      Dim first = lines.FirstOrDefault
      Dim last = lines.LastOrDefault
      
      Console.WriteLine("{1}{0}{2}{0}{3}",
          Environment.NewLine, first, last, watch.Elapsed)

      With my computer for a file of approx 150 000 words (generated via Lorem Ipsum)I got a time of 7 milliseconds

      • Proposed as answer by JohnWein Tuesday, February 05, 2013 11:25 PM
      • Marked as answer by Shanks ZenModerator Friday, February 15, 2013 9:32 AM
      Tuesday, February 05, 2013 10:58 PM
      Sehnsucht_Fr

      845
      Points
      Top 5
      Sehnsucht_Fr
      Joined Sep 2012

      1

      9

      845 Points

  • Most of the abstractions of the later frameworks have little use.  This is an example.  But it applies here.  Here it is in comprehensible format:

    Dim Lines As Collections.Generic.IEnumerable(Of String) = File.ReadLines(“Test.txt”)
    Dim Line0 As String = Lines.FirstOrDefault
    Dim LineN As String = Lines.LastOrDefault

    Tuesday, February 05, 2013 11:29 PM
    JohnWein

    90,015
    Points
    Top 0.1
    JohnWein
    Joined May 2008

    4

    5

    12

    Screen for lung cancer.

    90,015 Points

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s