我有一个表示项目的文件,在一行中有Item 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行。
有没有有效的方法呢?
答案 0 :(得分:3)
我认为完全使用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);
}
}
答案 1 :(得分:2)
我尝试了几种不同的方法来使用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
};
}
}