0

我目前正在编写一段代码,它逐行读取文件,将其拆分然后存储在数据结构中,即我有一行由空格分隔,我想拆分为 13 个元素,每个元素对应于一个结构中的项目。我正在尝试使用具有以下数据结构的 LINQ 来执行此操作:

public struct LogDetails
{
    public string LogDate { get; set; }
    public string LogTime { get; set; }
    public string csMethod { get; set; }
    public string csUriStem { get; set; }
    public string csUriQuery { get; set; }
    public string csUserName { get; set; }
    public string cIp { get; set; }
    public string csUserAgent { get; set; }
    public string csReferrer { get; set; }
    public string scStatus { get; set; }
    public string scSubStatus { get; set; }
    public string scBytes { get; set; }
    public string csBytes { get; set; }
}

我用于读取文件的 LINQ 代码如下所示:

var output = inputStream.ReadLine().Split(' ').GroupBy(f => f).AsEnumerable()
                                                      .SelectMany(g => g);

当我运行它时,它会按预期从文件中读取行并返回我需要填充结构的 13 个单独元素。但是,当我尝试检索这些元素时,我遇到了问题。理想情况下,我希望能够执行以下(非工作)代码:

IEnumerable<LogDetails> details = inputStream.ReadLine().Split(' ').GroupBy(f => f).AsEnumerable()
                                                     .SelectMany(g => new LogDetails
                                                                           {
                                                                               LogDate = g.ElementAt(0).ToString(),
                                                                               LogTime = g.ElementAt(1).ToString()
                                                                               //rest of the struct goes here
                                                                           }).ToList();

任何建议表示赞赏!

安德鲁

更新

感谢大家的回应。完整的代码,有兴趣的朋友如下:

IEnumerable<LogDetails> details = null;

details = File.ReadAllLines(pFileName)
               .Select(l => new { split = l.Split(' ') })
               .Select(s => new LogDetails
               {
                    LogDate = s.split.ElementAtOrDefault(0),
                    LogTime = s.split.ElementAtOrDefault(1),
                    csMethod = s.split.ElementAtOrDefault(2),
                    csUriStem = s.split.ElementAtOrDefault(3),
                    csUriQuery = s.split.ElementAtOrDefault(4),
                    csUserName = s.split.ElementAtOrDefault(5),
                    cIp = s.split.ElementAtOrDefault(6),
                    csUserAgent = s.split.ElementAtOrDefault(7),
                    csReferrer = s.split.ElementAtOrDefault(8),
                    scStatus = s.split.ElementAtOrDefault(9),
                    scSubStatus = s.split.ElementAtOrDefault(10),
                    scBytes = s.split.ElementAtOrDefault(11),
                    csBytes = s.split.ElementAtOrDefault(12)

                }).ToList();
4

3 回答 3

3

我不知道你为什么要使用GroupBy,我会使用File.ReadLines+ Enumerable.Select

IEnumerable<LogDetails> details = File.ReadLines(filePath)
    .Select(l => new { Split = l.Split() })
    .Select(x => new LogDetails
     {
        LogDate = x.Split.ElementAt(0),
        LogTime = x.Split.ElementAtOrDefault(1),
        //rest of the struct goes here
     });
于 2013-05-01T13:09:07.350 回答
2

我不起诉 Linq 是您最好的选择。Linq 将遍历拆分数组中的每个项目。您只需要使用数组中的项目初始化一个对象。

var items = inputStream.ReadLine().Split(' ');
var details new LogDetails {
                                 LogDate = items[0],
                                 LogTime = items[1]
                                 //rest of the struct goes here
                           };
于 2013-05-01T13:08:22.640 回答
0

您的最终解决方案有一些冗余,只是想稍微简化一下:

var details = 
    from line in File.ReadAllLines(pFileName)
    let tokens = line.Split(' ')
    select new LogDetails
    {
        LogDate     = tokens[0],
        LogTime     = tokens[1],
        csMethod    = tokens[2],
        csUriStem   = tokens[3],
        csUriQuery  = tokens[4],
        csUserName  = tokens[5],
        cIp         = tokens[6],
        csUserAgent = tokens[7],
        csReferrer  = tokens[8],
        scStatus    = tokens[9],
        scSubStatus = tokens[10],
        scBytes     = tokens[11],
        csBytes     = tokens[12]
    };
于 2013-05-01T19:58:12.723 回答