将日志文件保持在一定大小

我有一个应用程序在自助服务终端(C#/ WPF)中的独立面​​板PC上运行。 它对文本文件执行一些典型的日志记录操作。 PC具有一些有限的磁盘空间来存储这些日志。

我需要做的是能够指定允许日志文件的最大大小。 如果在尝试写入日志时超出最大大小,则会将新数据写入日志末尾,并从头开始清除最旧的数据。

获取文件大小没有问题,但有没有任何典型的文件操作技术来保持文件在一定的大小?

处理此问题的一种方法是拥有两个日志文件,每个日志文件的最大大小的一半。 当您达到每个文件的最大大小时,您只需在两者之间轮换。 旋转到文件会导致它被新文件覆盖。

日志框架(如log4net)内置了此function。

从文件开头剥离数据没有简单的方法。 所以你有几个选择:

  1. 如果所有日志文件的总大小超出限制,请将日志保留在几个较小的日志文件中并删除最旧的“块”。 这类似于你想要做的,但在不同的层面
  2. 将日志文件重命名为“log.date”并启动新日志。 与(1)类似,但如果磁盘空间有限,则不能选择。
  3. 如果你有足够的RAM并且你的日志大小相对较小以适应内存,你可以执行以下操作:使用内存映射文件将整个文件映射到内存中,然后通过从文件中间获取数据来执行移动操作将它们移到开头。 然后截断文件。 这是从日志文件开头轻松剥离数据而不创建数据副本的唯一方法。

Linux操作系统:查看logrotate – http://www.cyberciti.biz/faq/how-do-i-rotate-log-files/

Windows操作系统:尝试谷歌搜索Windows logrotate。 例如: http : //blog.arithm.com/2008/02/07/windows-log-file-rotation/

我不会将它用于一个意味着超过1兆的文件并且它的效率不是很高,但如果您需要解决一个棘手的问题,当您需要一个无法方便维护的日志文件时它会很好。 在使用之前确保日志文件存在…或者您可以为其添加代码以及检查位置是否存在等。

// This is how to call it private void buttonLog_Click(object sender, EventArgs e) { c_Log.writeToFile(textBoxMessages.Text, "../../log.log", 1); } public static class c_Log { static int iMaxLogLength = 15000; // Probably should be bigger, say 200,000 static int iTrimmedLogLength = -1000; // minimum of how much of the old log to leave static public void writeToFile(string strNewLogMessage, string strFile, int iLogLevel) { try { FileInfo fi = new FileInfo(strFile); Byte[] bytesSavedFromEndOfOldLog = null; if (fi.Length > iMaxLogLength) // if the log file length is already too long { using (BinaryReader br = new BinaryReader(File.Open(strFile, FileMode.Open))) { // Seek to our required position of what you want saved. br.BaseStream.Seek(iTrimmedLogLength, SeekOrigin.End); // Read what you want to save and hang onto it. bytesSavedFromEndOfOldLog = br.ReadBytes((-1 * iTrimmedLogLength)); } } byte[] newLine = System.Text.ASCIIEncoding.ASCII.GetBytes(Environment.NewLine); FileStream fs = null; // If the log file is less than the max length, just open it at the end to write there if (fi.Length < iMaxLogLength) fs = new FileStream(strFile, FileMode.Append, FileAccess.Write, FileShare.Read); else // If the log file is more than the max length, just open it empty fs = new FileStream(strFile, FileMode.Create, FileAccess.Write, FileShare.Read); using (fs) { // If you are trimming the file length, write what you saved. if (bytesSavedFromEndOfOldLog != null) { Byte[] lineBreak = Encoding.ASCII.GetBytes("### " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " *** *** *** Old Log Start Position *** *** *** *** ###"); fs.Write(newLine, 0, newLine.Length); fs.Write(newLine, 0, newLine.Length); fs.Write(lineBreak, 0, lineBreak.Length); fs.Write(newLine, 0, newLine.Length); fs.Write(bytesSavedFromEndOfOldLog, 0, bytesSavedFromEndOfOldLog.Length); fs.Write(newLine, 0, newLine.Length); } Byte[] sendBytes = Encoding.ASCII.GetBytes(strNewLogMessage); // Append your last log message. fs.Write(sendBytes, 0, sendBytes.Length); fs.Write(newLine, 0, newLine.Length); } } catch (Exception ex) { ; // Nothing to do... //writeEvent("writeToFile() Failed to write to logfile : " + ex.Message + "...", 5); } } }