在环顾四周一段时间时,我发现了一些关于如何计算文件中行数的讨论。
例如,这三个方面:
因此,我继续使用似乎最有效的方法(至少是内存方面的?)方法,我可以找到:
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()
,但是我不能(或者不知道如何使用)让他们中的任何一个在有'stuff‘(chars )的情况下立即转到下一行。短信?)。
有什么想法吗?
CONCLUSION/RESULTS (在根据提供的答案运行了一些测试之后):
我在两个不同的文件上测试了下面的5种方法,得到了一致的结果,似乎表明普通的旧StreamReader.ReadLine()
仍然是最快的方法之一.老实说,在回答所有的评论和讨论之后,我感到困惑。
文件#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-1-> 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;
}
发布于 2013-01-09 17:51:06
不,它不是。重点是-它将字符串具体化,这是不需要的。
要计数它,你最好忽略“字符串”部分和“行”部分。
一行是以\r\n (13,10-CRLF)或另一个标记结束的字节序列。
只需在缓冲流中沿字节运行,计算行尾标记的外观数。
发布于 2013-01-09 17:57:29
知道如何快速做到这一点的最好方法是不使用C/C++来思考最快的方法。
在程序集中,有一个CPU级操作,用于扫描内存中的字符,因此在程序集中,您将执行以下操作
因此,在C#中,您希望编译器尽可能接近它。
发布于 2013-01-09 21:20:05
我尝试了多种方法并测试了它们的性能:
读取单个字节的方法比其他方法慢约50%。其他方法都在相同的时间内返回。您可以尝试创建线程并异步执行此操作,因此在等待读取时,您可以开始处理上一次读取。听起来我有点头疼。
我将使用一个班轮:File.ReadLines(filePath).Count();
,它的性能与我测试的其他方法一样好。
private static int countFileLines(string filePath)
{
using (StreamReader r = new StreamReader(filePath))
{
int i = 0;
while (r.ReadLine() != null)
{
i++;
}
return i;
}
}
private static int countFileLines2(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 + 1;
}
}
private static int countFileLines3(string filePath)
{
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 + 1;
}
}
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;
}
private static int countFileLines4(string filePath)
{
return File.ReadLines(filePath).Count();
}
https://stackoverflow.com/questions/14243249
复制相似问题