如何更快/更智能地阅读文本文件?

Wil*_*lem 6 .net c# linq c#-4.0

我想知道是否有可能以text file更快,更智能的方式阅读.

这是我的数据的典型格式text file:

称之为"部分":

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:
Run Code Online (Sandbox Code Playgroud)

我在文本文件中有成千上万个.

是否有可能用LINQ"部分"来读它"部分"?我不想遍历每一行.

是否有可能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)
{
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 12

干得好:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

它的作用是:创建一个迭代器块(一个状态机,在迭代时读取并"生成"数据;它不会一次读取整个文件)扫描行; 如果它是卡片的末尾,则卡片"屈服"; 否则它会将数据添加到字典中进行存储.

注意:如果您有自己的class代表数据,那么您可以使用像Reflection或FastMember之类的东西来按名称设置值.

这不直接使用LINQ; 然而,它被实现一个可枚举的序列,它是LINQ-to-Objects的构建块,所以你可以使用 LINQ 来消耗它,即

var data = ReadParts("some.file").Skip(2).First(x => x["ID"] == "123");
Run Code Online (Sandbox Code Playgroud)