我想知道是否可以以更快,更智能的方式从文本文件中读取.
这是我在文本文件中的典型数据格式:
称之为“部分”:
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将其“部分”读作“部分”?我不想遍历每一行.
LINQ是否可以从ID:1开始;并在ENDCARD结束:?
原因是我想为每个“部分”创建一个对象……
我有这样的想法:
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) { }
解决方法
干得好:
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; } }
它的作用是:创建一个迭代器块(一个状态机,在迭代时读取并“生成”数据;它不会一次读取整个文件)扫描行;如果它是卡片的末尾,则卡片“屈服”;否则它会将数据添加到字典中进行存储.
注意:如果您有自己的表示数据的类,那么您可以使用像reflection或FastMember这样的名称来设置值.
这不直接使用LINQ;但是,它是作为一个可枚举的序列实现的,它是LINQ-to-Objects的构建块,所以你可以使用LINQ来消耗它,即
var data = ReadParts("some.file").Skip(2).First(x => x["ID"] == "123");