首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >StreamReader.Readline()真的是计算文件中行数最快的方法吗?

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

Stack Overflow用户
提问于 2013-01-09 17:45:16
回答 7查看 26.3K关注 0票数 14

在环顾四周一段时间时,我发现了一些关于如何计算文件中行数的讨论。

例如,这三个方面:

c#如何计算文本文件中的行数

确定文本文件中的行数。

如何快速计算线路数?

因此,我继续使用似乎最有效的方法(至少是内存方面的?)方法,我可以找到:

代码语言:javascript
运行
复制
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种方法:

代码语言:javascript
运行
复制
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;
}
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2013-01-09 17:51:06

不,它不是。重点是-它将字符串具体化,这是不需要的。

要计数它,你最好忽略“字符串”部分和“行”部分。

一行是以\r\n (13,10-CRLF)或另一个标记结束的字节序列。

只需在缓冲流中沿字节运行,计算行尾标记的外观数。

票数 9
EN

Stack Overflow用户

发布于 2013-01-09 17:57:29

知道如何快速做到这一点的最好方法是不使用C/C++来思考最快的方法。

在程序集中,有一个CPU级操作,用于扫描内存中的字符,因此在程序集中,您将执行以下操作

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

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

票数 5
EN

Stack Overflow用户

发布于 2013-01-09 21:20:05

我尝试了多种方法并测试了它们的性能:

读取单个字节的方法比其他方法慢约50%。其他方法都在相同的时间内返回。您可以尝试创建线程并异步执行此操作,因此在等待读取时,您可以开始处理上一次读取。听起来我有点头疼。

我将使用一个班轮:File.ReadLines(filePath).Count();,它的性能与我测试的其他方法一样好。

代码语言:javascript
运行
复制
        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();
        }
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14243249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档