【问题标题】:Searching in an unordered log file在无序的日志文件中搜索
【发布时间】:2011-08-30 20:38:29
【问题描述】:

在我工作的地方,我们有一个日志文件,其中包含如下行:

31201007061308000000161639030001

应该这样读:

31|年(4)|月(4)|日(2)|小时(2)|分钟(2)|000000|设施(3)|徽章(5)|0001

所以每条记录都应该有一行,但是会发生这样的事情:

31201007192000000000161206930004 31201007192001000000161353900004 31201031201007192004000000161204690004 31201007192004000000090140470004 31201007192005000000090148140004 3120100719200500031201007191515000000161597180001 31201007191700000000161203490001 31201007191700000000161203490001 31201007191700000000161202830001 31201007191700000000

那是因为应该读取文件的软件有时会丢失一些最新记录,并且负责人将较旧的记录复制到文件末尾。所以基本上就是这样,因为人为错误。

当记录未保存在数据库中时,我必须搜索文件。起初我只是做了一个遍历文件上每条记录的 cicle,但它真的很慢,上面提到的问题使它变慢了。我现在的方法是使用正则表达式,就像这样:

//Starts Reader
StreamReader reader = new StreamReader(path);
string fileLine = reader.ReadLine();
while (!reader.EndOfStream)
{
  //Regex Matcher
  Regex rx = new Regex(@"31\d\d\d\d\d\d\d\d\d\d\d\d000000161\d\d\d\d\d0001");

  //Looks for all valid lines
  MatchCollection matches = rx.Matches(fileLine);

  //Compares each match against what we are looking for
  foreach (Match m in matches)
  {
    string s = m.Value;
    compareLine(date, badge, s);
  }

  reader.ReadLine();
}
reader.Close(); //Closes reader

我的问题是:什么是搜索文件的好方法?我应该先订购/清洁它吗?

【问题讨论】:

  • 做一个命令行sort它会比你在c#中做的任何事情都快得多

标签: c# regex search


【解决方案1】:

您最好按照以下步骤操作:

  • 将每一行解析为一个对象。结构应该适合这些行。包括 DateTime 对象以及任何其他相关字段。如果您稍微清理一下,可以使用 Regex 轻松完成此操作。使用捕获组和中继器。一年内,您可以使用(\d{4}) 来连续获取4 个数字,而不是\d\d\d\d
  • 创建一个List<MyStruct>,将每一行作为一个对象保存。
  • 使用 LINQ 搜索列表,例如:

    var searchResults = 来自 MyList 中的每个条目
                        其中 eachEntry.Date > DateTime.Now
                        和 eachEntry.facility.Contains("003")
                        选择每个条目;

另外,将此行添加到您的正则表达式中,它会加快速度,只要几毫秒:

MatchCollection matches = rx.Matches(fileLine, RegexOptions.Compiled);

【讨论】:

    【解决方案2】:

    如果您(提前)知道您要查找的条目,即您确切地知道您要查找的日期、设施和批次,您根本不需要解析数据。生成预期的字符串并进行简单的字符串搜索而不是使用正则表达式可能会更快:

    string expectedValue = getExpectedValue(date, badge);
    // expectedValue = "31201007192000000000161206930004"
    foreach (string line in lines)
    {
        if (line.IndexOf(expectedValue) >= 0)
        {
              // record found
        }
    }
    

    如果您只对文件是否包含您的 id 感兴趣,您可以将完整的文件读入单个字符串并搜索

    string completeFile = GetFileContents(file);
    if (completeFile.IndexOf(expectedValue) >= 0)
    {
         // record found
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-23
      • 1970-01-01
      • 2011-09-18
      • 2011-05-01
      • 2015-04-10
      • 2018-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多