StreamReader.Readline()真的是计算文件中行数的最快方法吗?

ser*_*ave 13 c# lines readline streamreader peek

在环顾四周的时候,我发现了很多关于如何计算出文件中行数的讨论.

例如这三个:
c#我 如何计算
文本文件中的行数确定文本文件中的行数
如何快速计算行数?

那么,我继续前进并最终使用了我能找到的最有效(至少是内存方式?)方法:

private static int countFileLines(string filePath)
{
    using (StreamReader r = new StreamReader(filePath))
    {
        int i = 0;
        while (r.ReadLine() != null) 
        { 
            i++; 
        }
        return i;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当文件中的行本身非常长时,这将永远存在.真的没有更快的解决方案吗?

我一直试图使用StreamReader.Read()或者StreamReader.Peek()我不能(或者不知道如何)让它们中的任何一个一旦有'东西'(字符?文本?)就移动到下一行.

有什么想法吗?


结论/结果(根据提供的答案进行一些测试后):

我在两个不同的文件中测试了下面的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 - > 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;
}
Run Code Online (Sandbox Code Playgroud)

小智 9

不它不是.点是 - 它实现了字符串,这是不需要的.

要计算它,你最好忽略"字符串"部分并去"行"部分.

LINE是以\ r \n(13,10-CR LF)或另一个标记结尾的字节系列.

只需沿缓冲流中的字节运行,计算行结束标记的出现次数.

  • 我想我在这方面达到了这个水平,我不会冒犯.我不是在这里寻找"免费午餐",当人们在不知道完整故事的情况下判断你的时候,我就是不喜欢它.我非常感谢你的'回答',并且在我不断尝试解决这个问题的时候绝对会使用它,无论是否有代码示例.谢谢. (3认同)

Hog*_*gan 5

知道如何快速完成这项工作的最佳方法是在不使用C/C++的情况下考虑最快的方法.

在汇编中有一个CPU级操作,它扫描内存中的字符,因此在汇编时,您将执行以下操作

  • 将文件的大部分(或全部)读入内存
  • 执行SCASB命令
  • 根据需要重复

因此,在C#中,您希望编译器尽可能接近它.