使用LINQ和File.ReadAllLines()读取下一行
我有一个表示项目的文件,在一行中有项目GUID,后面有5行描述该项目 例子: 我正在尝试首先访问此文件,以使项目的GUID符合使用LINQ提供的标准,例如where line.Contains(“line1”)。。通过这种方式,我将获得整行,我将从那里提取GUID,我希望将此GUID传递给另一个函数,该函数应“再次”访问文件,找到该行(其中使用LINQ和File.ReadAllLines()读取下一行,linq,file,text-parsing,Linq,File,Text Parsing,我有一个表示项目的文件,在一行中有项目GUID,后面有5行描述该项目 例子: 我正在尝试首先访问此文件,以使项目的GUID符合使用LINQ提供的标准,例如where line.Contains(“line1”)。。通过这种方式,我将获得整行,我将从那里提取GUID,我希望将此GUID传递给另一个函数,该函数应“再次”访问文件,找到该行(其中line.Contains(“line1”)&&line.Contains(“8e2803d1-444a-4893-a23d-d3b4ba51baee”),并
line.Contains(“line1”)&&line.Contains(“8e2803d1-444a-4893-a23d-d3b4ba51baee”)
,并从该行开始读取接下来的5行
有什么有效的方法可以做到这一点吗?我认为完全使用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);
}
}
private void GetStuff()
{
var lines=File.ReadAllLines(“foo.txt”);
var result=newdictionary();
对于(var索引=0;索引<行.长度;索引+=6)
{
变量项=新
{
Guid=新Guid(行[索引]),
Description=lines.Skip(索引+1).Take(5).ToArray()
};
结果.添加(item.Guid,item.Description);
}
}
我用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
};
}
}
public IEnumerable GetLogData(字符串文件名)
{
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(文件名).GetEnumerator();
while(lines.MoveNext())
{
var line=(字符串)lines.Current;
var match=Regex.match(line,line1Regex);
如果(!match.Success)
继续;
var details=新字符串[detailLines];
对于(int i=0;i
您能提供更多详细信息吗?我不明白您是否在谈论单个文件……我还想知道,当我可以对文件进行LINQ查询时,是否可以获得行号。ReadAllLines(),知道吗?文件是否经常更改?如果不知道,可能值得将其转换为XML,然后在实际程序中使用XML。当然,您仍然需要处理文件一次才能进行转换,但之后您可以使用各种XML库中的任何一个。如果内容经常更改,这可能不划算o每次转换文件。文件的内容不会改变。这就像日志或其他东西。但问题是,当我在“aspx”页面中显示它们时,我仍然必须逐行检查它们,因为我会将这些行链接到DB条目“注释”.你是否在试图避免阅读整个文件,并寻找一种只阅读你需要的内容的方法?这将很困难,除非你能回答这样的问题:第5项第一行第一个字节的确切索引是什么?谢谢Daniel。在这种情况下,我有点担心大文件,我的意思是从b读取文件最后,有时我处理的文件高达20MB。有没有使用这种方式的性能控制器?另一件事是,每行GUID都有一个“类型”,并且每种类型都有一组不同的操作。因此,我将从该行中找到类型,将其与类型列表进行比较,然后继续…我觉得对文件中的每一行都这样做不好!如果您需要更具体的解决方案,您应该发布原始数据文件的一段代码。如果您关心性能,为什么o您认为多次打开和访问该文件会有帮助吗?
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
};
}
}