使用Linq解析文本文件

3

我有一个日志文件,格式如下所示,可以看到每个日志都以时间开始,并以管道分隔符结束。

将每个以日期时间开头并以管道分隔符结尾的日志放入列表中

我该如何解析这个文本文件并将日志放入集合中? 我似乎有一个问题,无法确定如何找到日志的开始和结束,并读取每个日志。

以下是一个快速示例,以给出我正在尝试做什么的想法。 任何指针帮助等...真的很感激

日志示例

        08:52:03.260|Error| Stack Trace and other info removed here|
        lots of info about the  stack trace
        lots of info about the  stack trace
        lots of info about the  stack trace
        lots of info about the  stack trace
        lots of info about the  stack trace|  
       09:52:03.260|Error| Stack Trace and other info removed here|
        lots of info about the  stack trace
        lots of info about the  stack trace
        lots of info about the  stack trace
         lots of info about the  stack trace
        lots of info about the  stack trace|
       09:52:03.260|Error|Stack Trace and other info removed here|
       lots of info about the  stack trace
       lots of info about the  stack trace
       lots of info about the  stack trace
       lots of info about the  stack trace
       lots of info about the  stack trace|

文件转场景 我的订单

        Quantity Description                    Price
        1        shoes                  £1.00
        Total                                   £1.00
        No:    34343345      


        =============================================
        My Order           


        Quantity Description                    Price
        1        TShirt        £1.00
        Total                                   £1.00
        No:    32234234



        ============================================

程序:

  class Program
  {
    static void Main(string[] args)
    {
        string path = @"MyTestLog.log";
        string aa = string.Empty;

        List<LogMessage>logMessages=new List<LogMessage>();
        using (StreamReader reader = new StreamReader(path))
        {
            //????
            logMessages.Add(new LogMessage
            {
                Time = ??,
                ErrorLevel = ,
                Details = ??
            });
        }
    }
}

public class LogMessage
{
    public DateTime Time { get; set; }
    public string ErrorLevel { get; set; }
    public string Details { get; set; }
    //other stuff here
}

Linq相对于传统的做法性能非常差。因此,在解析通常非常依赖性能的情况下要小心。 - user333306
1个回答

6
你可以尝试这个方法:
var list =
    from line in File.ReadAllLines("log.txt")
    where line.EndsWith("|")
    let parts = line.Split('|')
    where parts.Length >= 2
    where IsDateTime(parts[0])
    select new LogMessage()
    {
        Time = DateTime.Parse(parts[0]),
        ErrorLevel = parts[1],
        Details = parts[2]
    };

还有这个简单的辅助方法:

private static bool IsDateTime(string time)
{
    DateTime temp;
    return DateTime.TryParse(time, out temp);
}

更新: 当你使用.NET 4.0时,应该使用File.ReadLines替代File.ReadAllLines。这可以避免将整个文件加载到内存中。


我经常使用这种模式。它非常适合处理CSV或任何结构化文本文件。 - Slaggg
嗨,史蒂文。它运行得非常好!!!非常感谢。我能再冒昧问你一个问题吗?我有另一种情况,需要再次读取一个文件,但这次是一个包含订单的文件,每个订单都用“=================”分隔。我如何可能再次读取文件并将其放入集合中。请参见编辑后的问题。再次感谢。 - user451259
那是一个非常可怕的格式。你确定要解析它吗?尝试将输入文件更改为更安全的格式(例如XML)。此外,虽然我认为可以使用LINQ来完成,但你最好使用更加命令式的方法来解析这种格式。祝你好运。 - Steven
非常感谢您的帮助。我无法更改格式,因为我没有控制权。但我会找到另一种方法。 - user451259

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接