我有一个在亭(C#/ WPF)一个独立的平板电脑上运行的应用程序。它执行一些典型的伐木作业到一个文本文件中。该PC具有的磁盘空间,一些有限的,因为他们成长来存储这些日志。
我需要做的是能够指定一个日志文件,允许为最大尺寸。如果试图写入日志时,超过最大大小,新数据将被写入日志的末尾,最早的数据会从一开始就被清除。
获取文件的大小是没有问题的,但是否有任何典型的文件操作技术来保证文件一定规模下?
处理这种情况的一个技术是有其各自的最大尺寸的一半两个日志文件。您只需在两者之间旋转,到达每个文件的最大尺寸。旋转到一个文件导致它与一个新的文件被覆盖。
日志框架,例如log4net的内置了这个功能。
尝试使用log4net的
有没有简单的方法来从文件开始剥离数据。所以,你有几种选择:
Linux操作系统:退房logrotate的 - http://www.cyberciti.biz/faq/how-do-i-rotate-log-files/
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);
}
}
}
我想要一个简单的解决方案为好,但我不希望添加其他的依赖,所以我做了一个简单的方法。这有你需要比压缩旧文件到一个zip,你可以在这里找到的部分其他一切:Create zip file in memory from bytes (text with arbitrary encoding)
static int iMaxLogLength = 2000; // Probably should be bigger, say 200,000
static int KeepLines = 5; // minimum of how much of the old log to leave
public static void ManageLogs(string strFileName)
{
try
{
FileInfo fi = new FileInfo(strFileName);
if (fi.Length > iMaxLogLength) // if the log file length is already too long
{
int TotalLines = 0;
var file = File.ReadAllLines(strFileName);
var LineArray = file.ToList();
var AmountToCull = (int)(LineArray.Count - KeepLines);
var trimmed = LineArray.Skip(AmountToCull).ToList();
File.WriteAllLines(strFileName, trimmed);
string archiveName = strFileName + "-" + DateTime.Now.ToString("MM-dd-yyyy") + ".zip";
File.WriteAllBytes(archiveName, Compression.Zip(string.Join("\n", file)));
}
}
catch (Exception ex)
{
Console.WriteLine("Failed to write to logfile : " + ex.Message);
}
}
我有这个作为我的应用程序的初始化/重新初始化节的一部分,所以它得到了一天跑几次。
ErrorLogging.ManageLogs("Application.log");