在.NET中滚动日志文件中读取的最佳方法是什么?

时间:2009-01-13 00:14:55

标签: file logging .net-3.5

我需要读取.NET 3.5sp1中的滚动日志文件。我想知道最好的方法是什么?该文件可以变得非常大。我的想法是

  • 打开文件
  • 将文件读取到最后读取行(在第一种情况下,它为0)
  • 阅读所有剩余的行
  • 关闭流并记住读取的最后一个行号。
  • 稍等一下。
  • 冲洗/重复。

我不确定这是不是最好的方式,对内存有效,考虑到文件可能非常大。而且我也无法锁定日志文件:(

思想?

3 个答案:

答案 0 :(得分:1)

以下是使用FileSystem Watcher打开文件并在写入时读取新数据的示例:

http://www.codeproject.com/KB/cs/wintail.aspx

这个例子看起来不错,但是不要因为Pete的爱而且所有的东西都模糊地使用锁(这个)。这是坏的。使用一个新对象,您可以在该类中的所有对象之间共享。

如果您打开ReadOnly文件,则不应该有共享冲突,具体取决于附加到日志文件的程序打开文件的方式。

答案 1 :(得分:0)

获取文件长度并读取文件的最后一部分。找到第一个换行符并不难从此处显示所有内容。 FileStream具有Length属性,read方法允许您从一个地方读取到另一个地方。

史蒂文是对的。如果其他程序不需要独占访问权限,则可以打开只读状态。

答案 2 :(得分:0)

您可以直接附加到文件中,而不是跟踪您的位置吗?

    Object mLogLock = new Object(); //to make logging thread safe
    string mLogFile = ""; //set your log location
    string mLogDirectory = "";
    public void HandleMessage(string inMessage)
    {

        lock (mLogLock)
        {
            if (!System.IO.Directory.Exists(mLogDirectory ))
            {
                System.IO.Directory.CreateDirectory(mLogDirectory );
            }

            String theMessage = DateTime.Now.ToString("s");
            if (inMessage != null)
                theMessage += " : " + inMessage;

            StreamWriter sw = new StreamWriter(mLogFile, true);

            sw.WriteLine(theMessage );

            sw.Dispose();
            sw.Close();
        }
    }

否则,如果你有一个作家一次写作而其他东西正在消费,并且你没有锁定,那么你的程序破坏你的日志。这甚至都不是问题。您可以尝试通过打开文件来锁定文件,以便通过任何想要读取或写入的文件来进行独占读/写,但是当其他代码无法读取时会抛出异常。

如果日志文件在同一个程序中,您可以将所有信息保存在一个大型流中,如MemoryStream,并使用上面的StreamWriter代替(或同样)MemoryStream。然后,您的读者和编写者可以锁定MemoryStream,而不是文件本身。那会有帮助吗?