DotNet Visual Basic: Yet Another StreamReader q

  • dminder / 104 / Fri, 27 Mar 2009 21:27:00 GMT / Comments (5)
  • I am searching through thread after thread and not coming up with the answer....

    I open a streamreader and point it to a logfile. Done, Cool no problem. If I have not opened this file before I read the whole thing in at once to get to the end of stream, again no problem. I get/save the position by getting the .Length of the stream (not sure if this is best practice, only way I could figure how to do it). Once the filesystemwatcher triggers it comes back in and is supposed to move the last known position and read the next line. All I am getting is the last 2 characters of the line and the line is alot longer than that. What am I overlooking or not doing correctly here??

    Here is what I have gotten so far:

    Dim currLogFile As String=""
    Dim filepos As Long=0

    Private Sub ReadLogFile()
    If currLogFile = "" Then Exit Sub
    Dim fs As StreamReader = File.OpenText(currLogFile)
    Dim s As String

    Try
    'Check to see if there is a position
    If filepos = 0 Then
    filepos = fs.ReadToEnd().Length
    Exit Sub
    End If

    'Get to the last position in the file
    fs.BaseStream.Seek(filepos, SeekOrigin.Begin)

    'Read the last line added
    s = fs.ReadLine()

    'used for testing purposes to see what was read in
    MsgBox(s)

    Catch ex As Exception
    ShowErrorMessage(ex.ToString)
    Finally
    fs.Close()
    fs.Dispose()
    End Try
    End Sub

    Also, I need to know is this the best way to do this? This log file is a high volume log file and can be updated sometimes up to 20 times a second. I am only reading from it so that I can detect specific messages. I have little to no control over the size of the file or how fast it updates and it could be as large as 75 MB or so.

    Thanks all!

    D
  • Keywords:

    streamreader, dotnet, visual basic, vb, .net

  • http://dotnet.itags.org/dotnet-visual-basic/167/«« Last Thread - Next Thread »»
    1. Nice code.

      Are you saying that each time the file is updated you want a message box to appear showing only the new data that has appended to the end?

      If so everything looks good but you might want to change your code to this.

      s = fs.ReadToEnd

      I have know idea how efffecient this code is but hopefully it will help be able to move forward.

      cpcishere | Tues, 04 Dec 2007 13:38:00 GMT |

    2. I think the stream and basestream positions are not synchronised, try having a look at this it may help;

      http://msdn2.microsoft.com/en-us/library/system.io.streamreader.discardbuffereddata.aspx

      tinbeard | Tues, 04 Dec 2007 13:39:00 GMT |

    3. I implemented both suggestions plus also added in an update for the file position so it would take into account things that would be added. I am still only getting the last 2 characters of the last line of data. :( :cry:

      'Shows that I am importing the correct namespace :)
      Imports System.IO

      'Globals
      Dim currLogFile As String = ""
      Dim filepos As Long = 0

      Private Sub ReadLogFile()
      If currLogFile = "" Then Exit Sub
      Dim fs As StreamReader = File.OpenText(currLogFile)
      Dim s As String = ""

      Try
      'Check to see if there is a position
      If filepos = 0 Then
      filepos = fs.ReadToEnd.Length
      End If

      'Get the end of the file
      fs.DiscardBufferedData()
      fs.BaseStream.Seek(filepos, SeekOrigin.Begin)

      'Read the last line added
      s = fs.ReadToEnd.ToString

      'Used for testing purposes to see what was read in
      MsgBox(s)

      'Reset filepos to reflect added info
      filepos = fs.ReadToEnd.Length

      Catch ex As Exception
      ShowErrorMessage(ex.ToString)
      Finally
      fs.Close()
      fs.Dispose()
      End Try
      End Sub

      Private Sub EQ2LogFileWatcher_Changed(ByVal sender As Object, _
      ByVal e As System.IO.FileSystemEventArgs) Handles EQ2LogFileWatcher.Changed
      'This is where it sets the path for the log file to be read from
      Try
      If currLogFile = "" Then currLogFile = e.FullPath.ToString
      ReadLogFile()
      Catch ex As Exception
      ShowErrorMessage(ex.ToString)
      End Try
      End Sub

      dminder | Tues, 04 Dec 2007 13:40:00 GMT |

    4. Ok, I took a slightly different approach and I am not sure how much it will impact performance but it does the trick for now.

      Private Sub ReadLogFile()
      If currLogFile = "" Then Exit Sub
      Dim fs As StreamReader = File.OpenText(currLogFile)
      Dim s As String = ""
      Dim i As Long

      Try
      'Get a total Line Count from the GetGo
      If linecount = 0 Then
      Do While Not fs.EndOfStream
      fs.ReadLine()
      linecount += 1
      Loop
      linecount -= 1
      Else
      'move to LineCount
      Do While i < linecount
      fs.ReadLine()
      i += 1
      Loop
      End If

      'Read the last line added
      s = fs.ReadToEnd.ToString

      'Add 1 to LineCount
      linecount += 1

      'Used for testing purposes to see what was read in
      MsgBox(s)

      Catch ex As Exception
      ShowErrorMessage(ex.ToString)
      Finally
      fs.Close()
      fs.Dispose()
      End Try
      End Sub

      If anybody knows what I was doing incorrectly on the original code, please let me know. Just to give you an idea on how these log files can grow that I am working on. I took a snippet of one and it is 2876 lines of text to go through. To have to read every line for a live one, that I would guess is in excess of 100,000 lines would be ludicrous!!

      Thank you all again as always your input is muchly appreciated.

      D

      dminder | Tues, 04 Dec 2007 13:41:00 GMT |

    5. I think I might have figured it out.
      This works for me.

      Dim currLogFile As String=""
      Dim filepos As Long=0

      Private Sub ReadLogFile()
      If currLogFile = "" Then Exit Sub
      Dim fs As StreamReader = File.OpenText(currLogFile)
      Dim s As String

      Try
      'Check to see if there is a position
      If filepos = 0 Then
      filepos = fs.ReadToEnd().Length
      Exit Sub
      End If

      'Get to the last position in the file
      fs.BaseStream.Seek(filepos, SeekOrigin.Begin)

      'Read the last line added
      s = fs.ReadToEnd

      'used for testing purposes to see what was read in
      MsgBox(s)
      filepos += s.Length
      Catch ex As Exception
      ShowErrorMessage(ex.ToString)
      Finally
      fs.Close()
      fs.Dispose()
      End Try
      End Sub

      cpcishere | Tues, 04 Dec 2007 13:42:00 GMT |