Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm making a program that controls a game server. One of the functions I'm making, is a live server logfile monitor.

There is a logfile (a simple textfile) that gets updated by the server as it runs.

How do I continuously check the logfile and output it's content in a RichTextBox?

I did this simple function just try and get the content of the log. It will of course just get the text row by row and output it to my textbox. Also it will lock the program for as long as the loop runs, so I know it's useless.

public void ReadLog()
{
  using (StreamReader reader = new StreamReader("server.log"))
  {
    String line;
        
    // Read and display lines from the file until the end of the file is reached.
    while ((line = reader.ReadLine()) != null)
    {
      monitorTextBox.AppendText(line + "
");
      CursorDown();
    }
  }
}

But how would you go about solving the live monitoring as simple as possible?

*** EDIT ***

I'm using Prescots solution. great stuff.

At the moment I'm using a sstreamreader to put the text from the file to my textbox. I ran into the problem is that, whenever I tried to access any of the gui controls in my event handler the program just stopped with no error or warnings.

I found out that it has to do with threading. I solved that like this:

private void OnChanged(object source, FileSystemEventArgs e)
{
    if (monitorTextField.InvokeRequired)
    {
        monitorTextField.Invoke((MethodInvoker)delegate { OnChanged(source, e); });
    }
    else
    {
      StreamReader reader = new StreamReader("file.txt");

      monitorTextField.Text = "";
      monitorTextField.Text = reader.ReadToEnd();
      reader.Close();
      CursorDown();
    }
}

Now my only problem is that the file.txt is used by the server so I can't access it, since it's "being used by another process". I can't control that process, so maybe I'm out of luck.

But the file can be opened in notepad while the server is running, so somehow it must be possible. Perhaps I can do a temp copy of the file when it updates and read the copy. I don't know.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
207 views
Welcome To Ask or Share your Answers For Others

1 Answer

Check out the System.IO.FileSystemWatcher class:

public static Watch() 
{
    var watch = new FileSystemWatcher();
    watch.Path = @"D:mp";
    watch.Filter = "file.txt";
    watch.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite; //more options
    watch.Changed += new FileSystemEventHandler(OnChanged);
    watch.EnableRaisingEvents = true;
}

/// Functions:
private static void OnChanged(object source, FileSystemEventArgs e)
{
    if(e.FullPath == @"D:mpfile.txt")
    {
        // do stuff
    }
}

Edit: if you know some details about the file, you could handle the most efficent way to get the last line. For example, maybe when you read the file, you can wipe out what you've read, so next time it's updated, you just grab whatever is there and output. Perhaps you know one line is added at a time, then your code can immediately jump to the last line of the file. Etc.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...