使用StreamWriter实现滚动日志,并从顶部删除

gre*_*b64 9 c# file-io logging streamwriter winforms

我的C#winforms 4.0应用程序一直使用线程安全的编写器来执行内部调试日志信息.当我的应用程序打开时,它会删除该文件并重新创建它.当应用关闭时,它会保存文件.

我想要做的是修改我的应用程序,以便它可以附加而不是替换.这是一个简单的修复.

但是,这是我的问题:

我想保留我的日志文件AROUND 10兆字节.我的约束很简单.当您关闭文件时,如果文件大于10兆字节,则删除前10%.

是否有一种"更好"的方式,然后执行以下操作:

  1. 关闭文件
  2. 检查文件是否> 10 meg
  3. 如果是,请打开该文件
  4. 解析整个事情
  5. 剔除前10%
  6. 把文件写回来

编辑:好吧,我最后滚动自己(如下所示)移动到Log4Net的建议是一个很好的建议,但是学习新库和移动所有日志语句(数千)的时间不是时间对我试图做的小改进有效.

  private static void PerformFileTrim(string filename)
  {
     var FileSize = Convert.ToDecimal((new System.IO.FileInfo(filename)).Length);

     if (FileSize > 5000000)
     {
        var file = File.ReadAllLines(filename).ToList();
        var AmountToCull = (int)(file.Count * 0.33); 
        var trimmed = file.Skip(AmountToCull).ToList();
        File.WriteAllLines(filename, trimmed);
     }
  }
Run Code Online (Sandbox Code Playgroud)

小智 6

我曾经研究过这个,从来没有想过任何东西,但我可以在这里为你提供B计划:

我使用下面的选项保留最多3个日志文件.首先,创建日志文件1并将其附加到.当它超过maxsize时,将创建log 2和更高版本的log 3.当日志3太大时,将删除日志1,并将剩余的日志压入堆栈.

string[] logFileList = Directory.GetFiles(Path.GetTempPath(), "add_all_*.log", SearchOption.TopDirectoryOnly);
if (logFileList.Count() > 1)
{
    Array.Sort(logFileList, 0, logFileList.Count());
}

if (logFileList.Any())
{
    string currFilePath = logFileList.Last();
    string[] dotSplit = currFilePath.Split('.');
    string lastChars = dotSplit[0].Substring(dotSplit[0].Length - 3);
    ctr = Int32.Parse(lastChars);
    FileInfo f = new FileInfo(currFilePath);

    if (f.Length > MaxLogSize)
    {
        if (logFileList.Count() > MaxLogCount)
        {
            File.Delete(logFileList[0]);
            for (int i = 1; i < MaxLogCount + 1; i++)
            {
                Debug.WriteLine(string.Format("moving: {0} {1}", logFileList[i], logFileList[i - 1]));
                File.Move(logFileList[i], logFileList[i - 1]); // push older log files back, in order to pop new log on top
            }
        }
        else
        {
            ctr++;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


ant*_*duh 1

我正在查看 win32 api,我什至不确定是否可以使用本机 win32 vfs 调用来做到这一点,更不用说通过 .Net 了。

我唯一的解决方案是使用内存映射文件并手动移动数据,.Net 似乎从 .Net 4.0 开始支持这一点。

内存映射文件