Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 截断.NET中日志文件的开头_Vb.net_File_Logging_Truncate - Fatal编程技术网

Vb.net 截断.NET中日志文件的开头

Vb.net 截断.NET中日志文件的开头,vb.net,file,logging,truncate,Vb.net,File,Logging,Truncate,我有一个VB.NET应用程序,它以文本格式将状态写入日志文件。随着时间的推移,文件越来越大,我想知道是否有一种有效的方法来截断文件的开头 为了简化操作,我希望指定文件大小(例如2-3MB),并使用StreamWriter编写日志: Using strm As New IO.StreamWriter(filelocation.log, True) strm.WriteLine("msg to write") strm.Close() End Using 我曾考虑使用strm.Ba

我有一个VB.NET应用程序,它以文本格式将状态写入日志文件。随着时间的推移,文件越来越大,我想知道是否有一种有效的方法来截断文件的开头

为了简化操作,我希望指定文件大小(例如2-3MB),并使用StreamWriter编写日志:

Using strm As New IO.StreamWriter(filelocation.log, True)
    strm.WriteLine("msg to write")
    strm.Close()
End Using

我曾考虑使用
strm.BaseStream.Length
来确定要剪切多少文件,但通过使用
.SetLength
它将从文件的末尾进行剪切-这不是期望的结果。

为什么不检查文件的字节长度是否大于3MB,如果大于3MB,则覆盖它并重新写入。像这样的,(我是一个c#guy):

System.IO.FileInfo f=新文件信息(文件名); 如果(f.Length>(1024*1024*3)){ //文件超过3MB // //也许可以支持它? //然后。。。 使用(StreamWriter sw=新StreamWriter(文件名,false)) { //覆盖内容。。。。 } }否则{ //以正常方式打开附加模式 } 希望这有帮助, 顺致敬意,
Tom。

我强烈建议您查看以完成日志记录。它非常强大和灵活,并且有一种内置的方式,可以根据您指定的大小滚动日志。这不是你在这里寻找的答案,但它绝对值得研究。下面是调试期间日志记录的示例配置:

<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>
然后,当您要记录某些内容时,请执行以下操作:

log.Info("No resources available.");
// or
log.Fatal(exception.Message);
// or
log.Warn("Something bad may happen here.");
您不必担心创建流对象、关闭流、处理流等等,这非常重要。

一种方法可能是

  • 逐行读取原始文件(A)
  • 跳过不需要的行
  • 将所需行写入另一个文件(B)
  • 保存文件B
  • 删除文件A
  • 将文件B重命名为文件A

  • 您可以检查文件长度并以硬(脏)方式截断它:


    以下是我为此使用的几个函数:

    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);
        }
    }
    
    还有几件事需要考虑:

  • 您需要在锁(xxx)内运行这些消息,以便在发生“收缩”时,不会有其他消息试图写入文件
  • 收缩文件可能需要一些时间,因此对日志的写入应该在后台线程上进行

  • 我使用的快速简便的方法。此示例保留日志文件的最近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
    

    这可能会起作用,但我认为如果两个日志条目彼此非常接近,可能会导致写入文件或截断另一个日志条目的问题。我并不真的想走这条路,但我认为这是必须要做的。日志记录最初设计得非常简单,但为了正确地完成它,这是可行的。谢谢
      If New FileInfo("yourFilePathHere").Length > (2 ^ 21) Then
            File.WriteAllText("yourFilePathHere", _
            File.ReadAllText("yourFilePathHere").Substring(ToInt32(2 ^ 21)))
      End If
    
    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);
        }
    }
    
    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