Чтение следующей строки с помощью LINQ и File.ReadAllLines()
У меня есть файл, который представляет элементы, в одной строке есть элемент 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, например, where line.Содержит ("строка 1").. Таким образом, я получу всю строку, я извлеку оттуда GUID, я хочу передать этот GUID другой функции, которая должна получить доступ к файлу "снова", найти эту строку (где line.Contains("line1") && line.Contains("8e2803d1-444a-4893-a23d-d3b4ba51baee")
и считывает следующие 5 строк, начиная с этой строки.
2 ответа:
Я попробовал несколько различных способов сделать это с помощью LINQ, но ничто не позволило мне выполнить однократное сканирование файла. Для этого сценария, о котором вы говорите, Я бы спустился на перечисляемый уровень и использовал 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 }; } }
Я не думаю, что действительно имеет смысл использовать 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); } }