我有一个巨大的文本文件,我需要阅读。目前我正在阅读这样的文本文件..
string[] lines = File.ReadAllLines(FileToCopy);
但是这里所有的行都被存储在行数组中,然后根据条件正在以编程方式处理,这不是有效的方式,因为它首先将文本文件的无关行(行)读入数组并且相同方式将去处理。 所以我的问题是我可以从文本文件中读取行号。假设它上次读取10001行,下次它应该从10002开始。 怎么实现呢?
答案 0 :(得分:11)
嗯,你没有存储所有这些行 - 但你必须读取它们。除非行具有固定长度(以字节为单位,而不是字符),否则您希望能够跳到文件的特定部分?
要仅在内存中存储所需的行,请使用:
List<string> lines = File.ReadLines(FileToCopy).Skip(linesToSkip).ToList();
请注意,{4}在.NET 4中引入,并使用迭代器按需读取行,而不是将整个文件读入内存。
如果您只想处理一定数量的行,也可以使用Take
:
List<string> lines = File.ReadLines(FileToCopy)
.Skip(linesToSkip)
.Take(linesToRead)
.ToList();
例如,linesToSkip=10000
和linesToRead=1000
会为您提供10001-11000行。
答案 1 :(得分:3)
忽略这些线条,它们没用 - 如果每条线的长度不一样,你将不得不再一次读取它们,这是一个巨大的浪费。
而是使用文件流的位置。这样,您可以在第二次尝试时跳到那里,无需再次读取数据。之后,您只需在循环中使用ReadLine
,直到结束,并标记新的结束位置。
请不要使用ReadLines().Skip()
。如果你有一个10 GB的文件,它将读取所有10 GB,创建适当的字符串,扔掉它们,然后,最后,读取你想要读取的100个字节。那只是疯了:)当然,它比使用File.ReadAllLines
更好,但仅仅因为它不需要将整个文件保存在内存中。除此之外,你还在阅读文件的每个字节(你必须找出行结束的位置)。
从上一个已知位置读取的方法的示例代码:
string[] ReadAllLinesFromBookmark(string fileName, ref long lastPosition)
{
using (var fs = File.OpenRead(fileName))
{
fs.Position = lastPosition;
using (var sr = new StreamReader(fs))
{
string line = null;
List<string> lines = new List<string>();
while ((line = sr.ReadLine()) != null)
{
lines.Add(line);
}
lastPosition = fs.Position;
return lines.ToArray();
}
}
}
答案 2 :(得分:1)
嗯,你确实有数字索引形式的行号。记下先前读取的行数组索引,然后开始从下一个数组索引开始读取。
答案 3 :(得分:0)
使用Filestream.Position方法获取该文件的位置,然后设置位置。