這將需要存儲的內存量來處理「新」日誌文件,但如果你只想要5Mb,那麼它應該沒問題。如果您在談論Gb +,那麼您可能還有其他問題;然而,它仍然可以使用臨時文件和一些鎖定來完成。
如前所述,您可能會遇到競爭條件,但如果這是寫入此文件的唯一線程,則情況並非如此。這會將您當前的文字替換爲文件。
const int MAX_FILE_SIZE_IN_BYTES = 5 * 1024 * 1024; //5Mb;
const string LOG_FILE_PATH = @"ThisFolder\log.txt";
string newLogMessage = "Hey this happened";
#region Use one or the other, I mean you could use both below if you really want to.
//Use this one to save an extra character
if (!newLogMessage.StartsWith(Environment.NewLine))
newLogMessage = Environment.NewLine + newLogMessage;
//Use this one to imitate a write line
if (!newLogMessage.EndsWith(Environment.NewLine))
newLogMessage = newLogMessage + Environment.NewLine;
#endregion
int newMessageSize = newLogMessage.Length*sizeof (char);
byte[] logMessage = new byte[MAX_FILE_SIZE_IN_BYTES];
//Append new log to end of "file"
System.Buffer.BlockCopy(newLogMessage.ToCharArray(), 0, logMessage, MAX_FILE_SIZE_IN_BYTES - newMessageSize, logMessage.Length);
FileStream logFile = File.Open(LOG_FILE_PATH, FileMode.Open, FileAccess.ReadWrite);
int sizeOfRetainedLog = (int)Math.Min(MAX_FILE_SIZE_IN_BYTES - newMessageSize, logFile.Length);
//Set start position/offset of the file
logFile.Position = logFile.Length - sizeOfRetainedLog;
//Read remaining portion of file to beginning of buffer
logFile.Read(logMessage, logMessage.Length, sizeOfRetainedLog);
//Clear the file
logFile.SetLength(0);
logFile.Flush();
//Write the file
logFile.Write(logMessage, 0, logMessage.Length);
我寫這真快,我很抱歉,如果我走了1個地方。
你甚至確定你可以截斷這個日誌文件 - 也許服務已經打開它。您是否可以不定期地停止並重新啓動服務以使您能夠將文件垃圾? (ServiceController.Stop等) – 2013-02-15 22:19:04
@Ramhound我用File.ReadLines()(介紹在.NET 4.0中)的文件讀取到內存中的集合,然後用只有最後X項寫出一個新的日誌文件考慮。想知道是否有更簡單的方法來截斷文本文件中的前n行。 – amo 2013-02-15 22:21:15
@StephenByrne服務重啓不會重新初始化日誌文件。重新啓動時,它將繼續附加到現有文件。但是,我知道外部服務已停止,因此可以通過運行截斷例程來獲得文件的獨佔訪問權限。在這種情況下,對日誌文件的獨佔訪問不是問題。 – amo 2013-02-15 22:22:09