Как читать из текстового файла быстрее / умнее? - PullRequest
6 голосов
/ 18 января 2012

Я хочу знать, возможно ли читать из text file более быстрым и умным способом.

Это типичный формат моих данных в text file:

Назовите это «part»:

ID:1;
FIELD1 :someText;
FIELD2 :someText;
FIELD3 :someText;
FIELD4 :someText;
FIELD5 :someText;
FIELD6 :someText;
FIELD7 :someText;
FIELD8 :someText;
END_ID :
01: someData;
02: someData;
...
...
48: someData;
ENDCARD:

У меня их тысячи в текстовом файле.

Можно ли использовать LINQ, чтобы прочитать его «part» по «part»?Я не хочу перебирать каждую строку.

Возможно ли, чтобы LINQ начинался с ID:1; и заканчивался ENDCARD:?

Причина этого в том, что я хочу создать object для каждой "детали" ...

Я имел в виду нечто подобное:

string[] lines = System.IO.File.ReadAllLines(SomeFilePath);

//Cleaning up the text file of unwanted text
var cleanedUpLines = from line in lines
                     where !line.StartsWith("FIELD1")
                     && !line.StartsWith("FIELD5")
                     && !line.StartsWith("FIELD8")
                     select line.Split(':');

//Here i want to LINQtoText "part" by "part"

//This i do not want to do!!!
foreach (string[] line in cleanedUpLines)
{
}

1 Ответ

12 голосов
/ 18 января 2012

Вот, пожалуйста:

static void Main()
{
    foreach(var part in ReadParts("Raw.txt"))
    {   // all the fields for the part are available; I'm just showing
        // one of them for illustration
        Console.WriteLine(part["ID"]);
    }
}

static IEnumerable<IDictionary<string,string>> ReadParts(string path)
{
    using(var reader = File.OpenText(path))
    {
        var current = new Dictionary<string, string>();
        string line;
        while((line = reader.ReadLine()) != null)
        {
            if(string.IsNullOrWhiteSpace(line)) continue;
            if(line.StartsWith("ENDCARD:"))
            {
                yield return current;
                current = new Dictionary<string, string>();
            } else
            {
                var parts = line.Split(':');
                current[parts[0].Trim()] = parts[1].Trim().TrimEnd(';');
            }
        }
        if (current.Count > 0) yield return current;
    }
}

Что это делает: создает блок итератора (конечный автомат, который считывает и «выдает» данные во время итерации; он не читает весь файл за один раз)идти) который сканирует линии;если это конец карты, карта «уступила»;в противном случае он добавляет данные в словарь для хранения.

Примечание: если у вас есть собственный class, который представляет данные, то вы можете использовать что-то вроде отражения или FastMember , чтобы установитьзначения по имени.

Это не использует LINQ напрямую;однако он реализован как перечисляемая последовательность, которая является строительным блоком LINQ-to-Objects, поэтому вы можете потреблять это с LINQ, то есть

var data = ReadParts("some.file").Skip(2).First(x => x["ID"] == "123");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...