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

时间:2013-09-10 20:49:52

标签: c# regex loops logging streamreader

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

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:

如你所见,我不需要第一行 我目前正在使用一些正则表达式来解析每个文件:一个表达式确定我是否已经初始化" Logs"我不关心和抛弃的线;另一个确定我是否有一个" Good log entry&#34 ;,我保留并解析;一些好的日志条目跨越多行。我只是接受多行的日志。但是,代码当前还捕获第一个垃圾行,因为它与Regex视点中的多行日志注释无法区分。此外,从我所读的Regex不是这里的解决方案(Parsing a log file with regular expressions)。

有许多日志文件,它们可能会变得相当大。出于这个原因,我在缓冲之前每次只读取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,或者我应该考虑使用不同类型的文件阅读器?

2 个答案:

答案 0 :(得分:2)

你可以使用这样的东西:

而不是:

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;

答案 1 :(得分:1)

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

例如

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;
   }
}

或某些。