我正在制作一个控制游戏服务器的程序。我正在做的一个功能是实时服务器日志文件监视器。
有一个日志文件(一个简单的文本文件)在运行时由服务器更新。
如何连续检查日志文件并将其内容输出到RichTextBox中?
我做了这个简单的函数,只是尝试获取日志的内容。 当然,它只需要逐行获取文本并将其输出到我的文本框。 而且只要循环运行,它就会锁定程序,所以我知道它没用。
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 + "\n");
CursorDown();
}
}
}
但是,你将如何着手解决现场监测尽可能简单?
*编辑*
我用的是处方药。很棒的东西。
目前我正在使用sstreamreader将文件中的文本放到我的文本框中。我遇到的问题是,每当我试图访问我的事件处理程序中的任何gui控件时,程序只是在没有错误或警告的情况下停止。
我发现这和穿线有关。我是这样解决的:
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();
}
}
现在我唯一的问题是服务器使用了file.txt,所以我无法访问它,因为它“正在被另一个进程使用”。我无法控制这个过程。。所以也许我运气不好。
但是当serevr运行时,这个文件可以在记事本中打开,所以无论如何它必须是可能的。也许我可以在文件更新和读取副本时对其进行临时复制。不知道。。。
查看System.IO.FileSystemWatcher类:
编辑:如果你知道这个文件的一些细节,你可以用最有效的方法得到最后一行。例如,当你读文件的时候,你可以删除你读过的内容,所以下次更新的时候,你只要抓取其中的内容并输出。也许您知道一次添加一行,那么您的代码可以立即跳到文件的最后一行。等等
尽管
FileSystemWatcher
是最简单的解决方案,但我发现它在现实中是不可靠的。。通常,可以用新内容更新文件,但是FileSystemWatcher
直到几秒钟后才会触发事件,而且通常永远不会。我发现唯一可靠的方法是使用
System.Timers.Timer
对象定期检查对文件的更改并检查文件大小。我在这里写了一个小类来演示这一点:
https://gist.github.com/ant-fx/989dd86a1ace38a9ac58
示例用法
这里唯一真正的缺点(除了文件大小检查导致的轻微性能延迟外)是因为它使用了
System.Timers.Timer
回调来自不同的线程。如果您使用的是Windows窗体或WPF应用程序,则可以轻松地修改类以接受
SynchronizingObject
,这将确保从同一线程调用事件处理程序事件。正如@Prescott建议的那样,使用
FileSystemWatcher
。并确保以适当的FileShare模式打开该文件(FileShare.ReadWrite
似乎是适当的),因为该文件可能仍由服务器打开。如果试图在另一进程仍在使用该文件时以独占方式打开该文件,则打开操作将失败。另外,为了获得一点性能,您可以记住最后一个位置,您已经读取了该文件,并且只读取了新的部分。
相关问题 更多 >
编程相关推荐