我有一个VB.NET应用程序,它以文本格式将状态写入日志文件。随着时间的推移,文件变得越来越大,我想知道是否有一种有效的方法来截断文件的开头。
为了简化操作,我希望指定一个文件大小(比如2-3 MB),我正在使用StreamWriter编写日志:
Using strm As New IO.StreamWriter(filelocation.log, True)
strm.WriteLine("msg to write")
strm.Close()
End Using
我考虑使用strm.BaseStream.Length
来确定要截断的文件的数量,但是使用.SetLength
它会从最后剪切 - 而不是期望的结果。
答案 0 :(得分:2)
我强烈建议您查看log4net以完成日志记录。它非常强大和灵活,并且具有基于您可以指定的大小滚动日志的内置方式。这不是你在这里寻找的答案,但绝对值得研究。这是我们在调试期间为日志记录所做的示例配置:
<log4net>
<appender name="GeneralLog" type="log4net.Appender.RollingFileAppender">
<file value="ClientTools.log"/>
<appendToFile value="true"/>
<maximumFileSize value="3000KB"/>
<rollingStyle value="Size"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{HH:mm:ss} [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="GeneralLog"/>
</root>
<logger name="NHibernate" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="GeneralLog"/>
</logger>
</log4net>
app.config文件中的此代码将在应用程序文件夹中创建一个名为ClientTools.log的日志文件,以包含日期和时间的特定格式写入,并将日志滚动到3MB。
要使用记录器,我们在网页的Init()中执行此操作: 公共ILog日志;
public void InitiateLogging()
{
log4net.Config.XmlConfigurator.Configure();
log = LogManager.GetLogger("MyApplication");
}
然后当你想记录某些内容时,请执行以下操作:
log.Info("No resources available.");
// or
log.Fatal(exception.Message);
// or
log.Warn("Something bad may happen here.");
您不必担心创建流对象,关闭流,处理流等等。这非常DRY。
答案 1 :(得分:0)
为什么不检查文件的长度是否大于3MB,如果是,则覆盖它并重新写入。像这样的东西,(我是一个c#家伙):
System.IO.FileInfo f = new FileInfo(file_name); if (f.Length > (1024 * 1024 * 3)){ // File is over 3MB // // Perhaps back it up? // Then... using (StreamWriter sw = new StreamWriter(file_name, false)) { // Overwrite the contents.... } }else{ // Open as normal for append mode }
希望这有帮助, 最好的祝福, 汤姆。
答案 2 :(得分:0)
一种方法可能是
答案 3 :(得分:0)
您可以检查文件长度并将其截断为硬(和脏)方式:
If New FileInfo("yourFilePathHere").Length > (2 ^ 21) Then
File.WriteAllText("yourFilePathHere", _
File.ReadAllText("yourFilePathHere").Substring(ToInt32(2 ^ 21)))
End If
答案 4 :(得分:0)
以下是我使用的几个函数:
private void ShrinkLogFile()
{
var file = new FileInfo(Filename);
if (file.Exists && file.Length > MaxFileSize)
{
MoveLinesToBeginningStartingAt(file.Length - (MaxFileSize / 2));
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
private void MoveLinesToBeginningStartingAt(long offsetToKeep)
{
// Open the file twice. We'll read from the end and write to the beginning.
using (var fileReader = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var fileWriter = new FileStream(Filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
// Find the end of the first line so we start at the beginning of a new line.
fileReader.Position = offsetToKeep;
using (var reader = new StreamReader(fileReader, Encoding.UTF8, true, 512, true)) // Note that we leave fileReader open...
{
offsetToKeep += reader.ReadLine().Length; // Advance offset past the (probably) partial first line
offsetToKeep += Environment.NewLine.Length; // Advance past the newline
}
// Go to new position and copy the rest of the file to the beginning of the same file.
fileReader.Position = offsetToKeep;
fileReader.CopyTo(fileWriter);
// Truncate the file
var fileInfo = new FileInfo(Filename);
fileWriter.SetLength(fileInfo.Length - offsetToKeep);
}
}
还有其他一些事情需要考虑:
答案 5 :(得分:0)
我使用的快捷方法。此示例保留最新的60行日志文件。
dim LogPath as string = "YourLogPath"
Dim lineCount = File.ReadAllLines(LogPath).Length
If lineCount > 60 Then ' because I want my log to be 60 lines long
Dim delLineCount As Integer = lineCount - 60
Dim lines As List(Of String) = New List(Of String)(File.ReadAllLines(LogPath))
lines.RemoveRange(0, delLineCount)
File.WriteAllLines(LogPath, lines.ToArray())
End If