Чтение следующей строки с использованием LINQ и File.ReadAllLines () - PullRequest
3 голосов
/ 01 марта 2010

У меня есть файл, который представляет элементы, в одной строке есть GUID элемента, за которым следуют 5 строк, описывающих элемент.

Пример:

Line 1: Guid=8e2803d1-444a-4893-a23d-d3b4ba51baee name= line1 
Line 2: Item details = bla bla   
.  
.  
Line 7: Guid=79e5e39d-0c17-42aa-a7c4-c5fa9bfe7309 name= line7 
Line 8: Item details = bla bla    
.  
. 

Я пытаюсь сначала получить доступ к этому файлу, чтобы получить GUID элементов, отвечающих критериям, предоставленным с помощью LINQ, например. где line.Contains ("line1") .. Таким образом, я получу всю строку, оттуда извлеку GUID, хочу передать этот GUID другой функции, которая должна снова получить доступ к файлу, найти эту строку ( где line.Contains("line1") && line.Contains("8e2803d1-444a-4893-a23d-d3b4ba51baee") и читает следующие 5 строк, начиная с этой строки.

Есть ли эффективный способ сделать это?

Ответы [ 2 ]

3 голосов
/ 01 марта 2010

Я не думаю, что на самом деле имеет смысл использовать LINQ полностью, учитывая требования того, что вам нужно сделать, и учитывая, что индекс строки в массиве является просто интегральным. Я также рекомендовал бы делать все за один проход - многократное открытие файла не будет таким же эффективным, как простое чтение всего один раз и немедленная обработка. Пока файл структурирован так, как вы его описали, это не будет очень сложно:

    private void GetStuff()
    {
        var lines = File.ReadAllLines("foo.txt");
        var result = new Dictionary<Guid, String[]>();
        for (var index = 0; index < lines.Length; index += 6)
        {
            var item = new
            {
                Guid = new Guid(lines[index]),
                Description = lines.Skip(index + 1).Take(5).ToArray()
            };
            result.Add(item.Guid, item.Description);
        }
    }
2 голосов
/ 01 марта 2010

Я попробовал несколько разных способов сделать это с помощью LINQ, но ничто не позволило мне выполнить одно сканирование файла. Для этого сценария, о котором вы говорите, я бы опустился до уровня Enumerable и использовал бы GetEnumerator следующим образом:

public IEnumerable<LogData> GetLogData(string filename)
{
    var line1Regex = @"Line\s(\d+):\sGuid=([0123456789abcdefg]{8}-[0123456789abcdefg]{4}-[0123456789abcdefg]{4}-[0123456789abcdefg]{4}-[0123456789abcdefg]{12})\sname=\s(\w*)";
    int detailLines = 4;

    var lines = File.ReadAllLines(filename).GetEnumerator();
    while (lines.MoveNext())
    {
        var line = (string)lines.Current;
        var match = Regex.Match(line, line1Regex);
        if (!match.Success)
             continue;

        var details = new string[detailLines];
        for (int i = 0; i < detailLines && lines.MoveNext(); i++)
        {
            details[i] = (string)lines.Current;
        }

        yield return new LogData
        {
            Id = new Guid(match.Groups[2].Value),
            Name = match.Groups[3].Value,
            LineNumber = int.Parse(match.Groups[1].Value),
            Details = details
        };
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...