我想逐行阅读一个文本文件。我想知道我是否在.NET C#范围内尽可能高效地完成了这项工作。
这就是我到目前为止一直在尝试的:
var filestream = new System.IO.FileStream(textFilePath,
System.IO.FileMode.Open,
System.IO.FileAccess.Read,
System.IO.FileShare.ReadWrite);
var file = new System.IO.StreamReader(filestream, System.Text.Encoding.UTF8, true, 128);
while ((lineOfText = file.ReadLine()) != null)
{
//Do something with the lineOfText
}发布于 2011-11-07 23:41:29
要找到逐行读取文件的最快方法,您必须进行一些基准测试。我已经在我的计算机上做了一些小测试,但您不能期望我的结果适用于您的环境。
使用StreamReader.ReadLine的
这基本上就是你的方法。由于某些原因,您将缓冲区大小设置为可能的最小值(128)。增加这个值通常会提高性能。默认大小是1,024,其他好的选择是512 (Windows中的扇区大小)或4,096 (NTFS中的集群大小)。您必须运行基准测试来确定最佳缓冲区大小。较大的缓冲区即使不是更快,至少也不会比较小的缓冲区慢。
const Int32 BufferSize = 128;
using (var fileStream = File.OpenRead(fileName))
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) {
String line;
while ((line = streamReader.ReadLine()) != null)
// Process line
}FileStream构造函数允许您指定FileOptions。例如,如果您从头到尾按顺序读取一个大文件,您可能会从FileOptions.SequentialScan中受益。同样,基准测试是您能做的最好的事情。
使用File.ReadLines的
这与您自己的解决方案非常相似,不同之处在于它是使用固定缓冲区大小为1,024的StreamReader实现的。在我的计算机上,与缓冲区大小为128的代码相比,这会产生稍微更好的性能。但是,您可以通过使用更大的缓冲区大小来获得相同的性能提升。此方法是使用迭代器块实现的,并且不会消耗所有行的内存。
var lines = File.ReadLines(fileName);
foreach (var line in lines)
// Process line使用File.ReadAllLines的
这与前面的方法非常相似,不同之处在于此方法增加了用于创建返回的行数组的字符串列表,因此内存要求更高。但是,它返回String[],而不是允许您随机访问这些行的IEnumerable<String>。
var lines = File.ReadAllLines(fileName);
for (var i = 0; i < lines.Length; i += 1) {
var line = lines[i];
// Process line
}使用String.Split的
这种方法相当慢,至少在大文件上(在511KB的文件上进行了测试),可能是由于String.Split的实现方式。它还为所有行分配一个数组,与您的解决方案相比,增加了所需的内存。
using (var streamReader = File.OpenText(fileName)) {
var lines = streamReader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
// Process line
}我的建议是使用File.ReadLines,因为它干净高效。如果您需要特殊的共享选项(例如,您使用FileShare.ReadWrite),您可以使用自己的代码,但应该增加缓冲区大小。
发布于 2011-11-07 21:26:40
如果您使用的是.NET 4,只需使用File.ReadLines,它会为您完成所有这些工作。我怀疑它和你的差不多,除了它可能也使用FileOptions.SequentialScan和一个更大的缓冲区(128看起来很小)。
发布于 2014-07-23 21:12:44
虽然File.ReadAllLines()是读取文件的最简单的方法之一,但它也是最慢的方法之一。
如果您只想读取文件中的行,而不想做太多操作,according to these benchmarks,读取文件的最快方法是古老的方法:
using (StreamReader sr = File.OpenText(fileName))
{
string s = String.Empty;
while ((s = sr.ReadLine()) != null)
{
//do minimal amount of work here
}
}然而,如果你必须对每一行做很多事情,那么this article的结论是最好的方法如下(如果你知道你要读多少行,那么预先分配一个string[]会更快):
AllLines = new string[MAX]; //only allocate memory here
using (StreamReader sr = File.OpenText(fileName))
{
int x = 0;
while (!sr.EndOfStream)
{
AllLines[x] = sr.ReadLine();
x += 1;
}
} //Finished. Close the file
//Now parallel process each line in the file
Parallel.For(0, AllLines.Length, x =>
{
DoYourStuff(AllLines[x]); //do your work here
});https://stackoverflow.com/questions/8037070
复制相似问题