Avatar billede kewl Nybegynder
13. marts 2006 - 11:23 Der er 8 kommentarer og
2 løsninger

Læse en logfil

kan det ikke lade sig gøre at blve ved med at prøve at læse næste linje i en åben logfil?

Jeg er ved at lave et program som løbende skal analysere en logfil, dvs. den skal kun læse frem mod enden af filen.

PS. Filen er åben af et andet program som skriver til filen. filen er 200 - 300 mb stor og vil helst ikke genindlæse hele filen hele tiden.
Avatar billede bernhof Nybegynder
13. marts 2006 - 13:37 #1
Det kan godt lade sig gøre.

Er det noget i denne stil du leder efter?


  Dim file As New IO.FileStream("C:\sti\til\fil.log", IO.FileMode.Open, _
                                IO.FileAccess.Read, IO.FileShare.ReadWrite)
  Dim reader As New IO.StreamReader(file)

  '...
  reader.ReadLine()
  '...

  reader.Close()
Avatar billede bernhof Nybegynder
13. marts 2006 - 13:43 #2
Hmmm.. Måske misfostod jeg.

Mener du, at du vil tjekke, om der er blevet tilføjet en linie til loggen, og hvis der er, vil du indlæse den - alt imens filen er åben i både din applikation og programmet, som skriver til loggen?
Avatar billede kewl Nybegynder
13. marts 2006 - 14:17 #3
Det du har skrevet åbner kun filen så den er klar til at blive læst, det programmet skal, er at blive ved med at forsøge at læse næste linje selvom den har nået bunden af filen, og når der så bliver skrevet en ny linje af det eksterne program (som har skrive adgang) skal denne kunne bruges af mit program.

skriv hvis det er helt hen i verjret det jeg har skrevet :)
Avatar billede bernhof Nybegynder
13. marts 2006 - 15:20 #4
Hehe, nej - jeg forstår :)

Jeg kan fortælle, at du I ovenstående eksempel kan benytte reader.Peek, som returerer -1 hvis der ikke er mere at læse i filen.

Fx


  If reader.Peek = -1 Then
    'Ikke mere at læse
  Else
    myLine = reader.ReadLine
  End If
Avatar billede bernhof Nybegynder
13. marts 2006 - 15:37 #5
Prøv noget i stil med følgende:


  Dim m_Cancel As Boolean

  Public Sub StartRead(ByVal pLogFile As String)
    m_Cancel = False
    Dim file As New IO.FileStream(pLogFile, IO.FileMode.Open, _
                                  IO.FileAccess.Read, IO.FileShare.ReadWrite)
    Dim reader As New IO.StreamReader(file)
    Try
      Dim Line As String
      Do Until m_Cancel = True
        If reader.Peek > -1 Then
          Line = reader.ReadLine
        Else
          'Stop tråden i 1 sekund og prøv igen
          System.Threading.Thread.CurrentThread.Sleep(1000)
        End If
      Loop
    Finally
      reader.Close()
    End Try
  End Sub

  Public Sub StopRead()
    m_Cancel = True
  End Sub


Et kald til fx StartRead("C:\sti\til\fil.log") vil få den til at forsøge at læse fra filen, og så snart den når slutningen af filen, venter den et sekund, og prøver at læse igen. For at stoppe denne proces, kalder du StopRead(). Den sætter en member variabel, m_Cancel, til True, hvilket får Do-Loop'et i StartRead metoden til at afslutte.

Har ikke testet ovenstående i praksis, så du må sige til, hvis det ikke virker.
Avatar billede arne_v Ekspert
13. marts 2006 - 15:45 #6
foelgende er en konvertering af noget C# kod ejeg lavede for en maaned siden:

Imports System
Imports System.IO
Imports System.Threading

Namespace E
    Public Class TailSniff
        Private filename As String
        Private pos As Long

        Public Sub New(ByVal filename As String)
            Me.filename = filename
            pos = 0
        End Sub
        Public Function Read() As StreamReader
            Dim fs As FileStream = New FileStream(filename, FileMode.Open, FileAccess.Read)
            Dim len As Long = fs.Length
            fs.Seek(pos, SeekOrigin.Begin)
            Dim b(len - pos) As Byte
            fs.Read(b, 0, b.Length)
            fs.Close
            pos = len
            Return New StreamReader(New MemoryStream(b))
        End Function
    End Class

    Public Class MainClass
        Public Shared Sub Main(ByVal args As String())
            Dim ts As TailSniff = New TailSniff("C:\z.z")
            While True
                Dim sr As StreamReader = ts.Read
                While sr.Peek > 0
                    Dim line As String = sr.ReadLine
                    Console.WriteLine(line)
                End While
                sr.Close
                Thread.Sleep(10)
            End While
        End Sub
    End Class
End Namespace
Avatar billede kewl Nybegynder
14. marts 2006 - 00:35 #7
Takker jeg kunne bruge dele fra jer begge, i må gerne lægge et svar.
Avatar billede arne_v Ekspert
14. marts 2006 - 04:31 #8
svar
Avatar billede bernhof Nybegynder
14. marts 2006 - 10:05 #9
svar
Avatar billede kewl Nybegynder
14. marts 2006 - 10:30 #10
Jeg har lige et tillægs spørgsmål, som kan ses her

http://www.eksperten.dk/spm/694976
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester