【发布时间】:2013-01-09 17:45:16
【问题描述】:
环顾四周,我发现了很多关于如何计算文件中行数的讨论。
例如这三个:
c# how do I count lines in a textfile
Determine the number of lines within a text file
How to count lines fast?
所以,我继续并最终使用了我能找到的最有效(至少在内存方面?)的方法:
private static int countFileLines(string filePath)
{
using (StreamReader r = new StreamReader(filePath))
{
int i = 0;
while (r.ReadLine() != null)
{
i++;
}
return i;
}
}
但是当文件中的行本身很长时,这需要很长时间。真的没有更快的解决方案吗?
我一直在尝试使用StreamReader.Read() 或StreamReader.Peek(),但我不能(或不知道如何)让它们中的任何一个在出现“东西”后立即进入下一行(字符?文本?)。
有什么想法吗?
结论/结果(根据提供的答案运行一些测试后):
我在两个不同的文件上测试了下面的 5 种方法,我得到了一致的结果,这似乎表明普通的旧 StreamReader.ReadLine() 仍然是最快的方法之一......老实说,在所有 cmets 之后我都感到困惑并在答案中讨论。
文件 #1:
大小:3,631 KB
行数:56,870
文件 #1 的结果(以秒为单位):
0.02 --> ReadLine 方法。
0.04 --> 读取方法。
0.29 --> ReadByte 方法。
0.25 --> Readlines.Count 方法。
0.04 --> ReadWithBufferSize 方法。
文件 #2:
大小:14,499 KB
行数:213,424
文件 #1 的结果(以秒为单位):
0.08 --> ReadLine 方法。
0.19 --> 读取方法。
1.15 --> ReadByte 方法。
1.02 --> Readlines.Count 方法。
0.08 --> ReadWithBufferSize 方法。
根据收到的所有反馈,我测试了以下 5 种方法:
private static int countWithReadLine(string filePath)
{
using (StreamReader r = new StreamReader(filePath))
{
int i = 0;
while (r.ReadLine() != null)
{
i++;
}
return i;
}
}
private static int countWithRead(string filePath)
{
using (StreamReader _reader = new StreamReader(filePath))
{
int c = 0, count = 0;
while ((c = _reader.Read()) != -1)
{
if (c == 10)
{
count++;
}
}
return count;
}
}
private static int countWithReadByte(string filePath)
{
using (Stream s = new FileStream(filePath, FileMode.Open))
{
int i = 0;
int b;
b = s.ReadByte();
while (b >= 0)
{
if (b == 10)
{
i++;
}
b = s.ReadByte();
}
return i;
}
}
private static int countWithReadLinesCount(string filePath)
{
return File.ReadLines(filePath).Count();
}
private static int countWithReadAndBufferSize(string filePath)
{
int bufferSize = 512;
using (Stream s = new FileStream(filePath, FileMode.Open))
{
int i = 0;
byte[] b = new byte[bufferSize];
int n = 0;
n = s.Read(b, 0, bufferSize);
while (n > 0)
{
i += countByteLines(b, n);
n = s.Read(b, 0, bufferSize);
}
return i;
}
}
private static int countByteLines(byte[] b, int n)
{
int i = 0;
for (int j = 0; j < n; j++)
{
if (b[j] == 10)
{
i++;
}
}
return i;
}
【问题讨论】:
-
read() 或 peek() 如何知道下一行在流中的位置?
-
@John 通过查找
\n和\r字符。 -
每一行的字节数是否完全相同,或者几乎完全相同?如果它们是准确的,你可以只计算文件大小,如果它们很接近,你可以根据平均行长度得出一个接近的近似值。
-
我指的是关于让流向前跳转的评论
-
@John:谢谢,约翰。你的回答(?)帮助我意识到我看错了地方,即使你的意思是讽刺。
标签: c# streamreader readline lines peek