繁体   English   中英

使用C#StreamReader循环跳过日志文件中的第一行

[英]Skip first line in log file using C# StreamReader in a loop

我有几个日志文件需要根据时间戳进行解析和合并。 它们的格式为:

GaRbAgE fIrSt LiNe
[1124 0905 134242422       ] Logs initialized
[1124 0905 134242568 SYSTEM] Good log entry:
{ Collection:
  ["Attribute"|String]
...
[1124 0905 135212932 SYSTEM] Good log entry:

如您所见,我不需要第一行。
我当前正在使用一些正则表达式来解析每个文件:一个表达式确定我是否有“日志初始化”行,我不在乎并丢弃它; 另一个决定我是否保存并解析了一个“良好的日志条目”; 和一些好的日志条目跨越多行。 我只是接受多行日志。 但是,该代码当前还捕获了第一条垃圾行,因为从Regex观点来看,它与多行日志注释是无法区分的。 此外,据我了解,Regex不是这里的解决方案( 使用正则表达式解析日志文件 )。

日志文件很多,它们可能会变得很大。 因此,在缓冲之前,每个日志一次只能读取50行,然后将它们合并到一个单独的文件中。 只要剩下非空文件,我就会遍历每个文件。 下面是一个代码示例,其中我用解释替换了一些条件和变量。

while (there are non-null files left to read)
     {
        foreach (object logFile in logFiles) //logFiles is an array that stores the log names
        {
           int numLinesRead = 0;
           using (StreamReader fileReader = File.OpenText(logFile.ToString()))
           {
              string fileLine;
              // read in a line from the file
              while ((fileLine = fileReader.ReadLine()) != null && numLinesRead < 50)
              {
                 // compare line to regex expressions
                 Match rMatch = rExp.Match(fileLine);
                 if (rMatch.Success)  // found good log entry
                 {
                 ...

您将如何跳过第一条垃圾线? 不幸的是,这并不像使用ReadLine()消耗一行那样容易,因为StreamReader处于循环内,而我最终每隔50条删除一行。
我想保留一个文件列表或文件数组,但我已经跳过了该文件的第一行(以便不多次跳过它),但这有点丑陋。 我还想摆脱循环中的using语句,并在循环之前打开StreamReader,但我不想这样做。

发布后进行编辑 ,我只是意识到我的实现可能根本不正确。 当StreamReader关闭并处理时,我相信我在文件中的先前位置将丢失。 在那种情况下,我是否应该仍在不using构造的情况下使用StreamReader,还是应该考虑使用其他类型的文件阅读器?

您可以只使用以下内容:

代替这个:

using (StreamReader fileReader = File.OpenText(logFile.ToString()))
{
    string fileLine;
    // read in a line from the file
    while ((fileLine = fileReader.ReadLine()) != null && numLinesRead < 50)
    {

做这个:

int numLinesRead = 0;

foreach (var fileLine in File.ReadLines(logFile.ToString()).Skip(1))
{
    if (++numLinesRead >= 50)
        break;

将另一个参数添加到文件中位置的方法中。 第一次为零,进入循环之前就可以消耗该行。 之后,您可以使用它将流定位到最后一个中断的位置。

例如

long position = 0;
while position >= 0
{
  position = ReadFiftyLines(argLogFile,0);
}
public long ReadFiftyLines(string argLogFile, long argPosition)
{
   using(FileStream fs = new FileStream(argLogFile,FileMode.Open,FileAccess.Read))
   {
       string line = null;
       if (argPosition == 0)
       {
          line = reader.Readline();
          if (line == null)
          {
             return -1; // empty file
          }
       }
       else
       { 
          fs.Seek(argPosition,SeekOrigin.Begin);
       }
       StreamReader reader = new StreamReader(fs);
       int count = 0;
       while ((line = reader.ReadLine() != null) && (count < 50))
       {
          count++;
          // do stuff with line
       }
       if (line == null)
       {
          return -1; // end of file
       }
       return fs.Position;
   }
}

或类似的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM