2

我正在尝试在日志文件的文本框中添加新行,日志文件会经常更新。我有一个FileSystemWatcher检查文件中的任何更新并触发onChange()event 。

textbox1.Text = File.ReadAllText(@"D:\Serverlogs\clientList.log");

这将获取整个文件的内容,随着日志大小的增长,这个操作变得越来越慢。如何读取更新的行而不是整个文件?

服务器会将新登录用户列表更新到日志中,例如文件和文本框中有15行文本,服务器每次新登录后都会更新文件,我只需要阅读第16行线 。

4

1 回答 1

4

我认为您必须跟踪您在文件中读取的最后一个位置,然后当您检测到更改时:打开文件,寻找正确的位置,然后读到最后。然后将其解析成行以添加到文本框中。

编辑: 这是一个演示这一点的工作控制台应用程序。你会想要更多的错误检查、初始化等等。旧代码只是一个猜测,但基本上是正确的。

class Program
{
    static FileSystemWatcher fs = null;
    static string fileName = @"c:\temp\log.txt";
    static long oldPosition = 0;

    static void Main(string[] args)
    {
        fs = new FileSystemWatcher(Path.GetDirectoryName(fileName));
        fs.Changed += new FileSystemEventHandler(fs_Changed);
        fs.EnableRaisingEvents = true;
        Console.WriteLine("Waiting for changes to " + fileName);
        Console.ReadLine();
    }

    static void fs_Changed(object sender, FileSystemEventArgs e)
    {
        if (e.FullPath != fileName || e.ChangeType != WatcherChangeTypes.Changed) return;
        using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        using (StreamReader fr = new StreamReader(fs))
        {
            Console.WriteLine("{0} changed.  Old Postion = {1}, New Length = {2}", e.Name, oldPosition, fs.Length);
            if (fs.Length > oldPosition)
            {
                fs.Position = oldPosition;
                var newData = fr.ReadToEnd();
                Console.WriteLine("~~~~~~ new data ~~~~~~\n" + newData);
                oldPosition = fs.Position;
            }
        }
    }
}
于 2013-09-25T07:03:16.500 回答