【问题标题】:StreamReader very slow for big filesStreamReader 对于大文件非常慢
【发布时间】:2016-04-22 08:28:06
【问题描述】:

我想读入一个在本例中为 3mb 的文件 这样做大约需要 50-60 秒,这似乎很慢。有谁知道如何加快速度?

string text = null;
using (StreamReader sr = new StreamReader(file, Encoding.Default))
{
    string line;
    while ((line = sr.ReadLine()) != null)
    {
        text += (line);
        backgroundWorker1.ReportProgress(text.Length);
    }
}

我还需要使用后台工作程序,以便报告已加载的百分比(对于 500mb 到 1gb 左右的文件)

【问题讨论】:

  • 您是否尝试过您的测试而不连接到System.String,即注释掉text += (line); 行?
  • 也许您不想按行读取,但缓冲区长度固定。
  • @Christian.K 我做到了,而且很快。现在我将如何获取文本?
  • 查看@RB 的回答(改用StringBuilder)。

标签: c# streamreader


【解决方案1】:

使用 StringBuilder 来创建你的行 - 它比字符串连接更高效。

using System.Text;

//...

StringBuilder text = new StringBuilder();
using (StreamReader sr = new StreamReader(file, Encoding.Default))
{
    string line;
    while ((line = sr.ReadLine()) != null)
    {
        text.Append(line);
        backgroundWorker1.ReportProgress(text.Length);
    }
}

// ...
// Do something with the file you have read in.
Console.WriteLine(text.ToString());

【讨论】:

  • 这将导致 NullReferenceException;看起来 text 从未初始化?
  • text 初始化...为null(sn-p 的第三个非空行)。
【解决方案2】:

StreamReader 对于大文件 C# 非常慢

不,不是。如果您已经完成了运行分析器的基本作业,您会发现您所花费的时间并没有花在流阅读器上。

文本 +=(行);

这一行正在创建一个新字符串。为此必须分配新的内存。对于大文件,这会产生大量垃圾。而且时间越长,你做的复制操作就越多。

如果这就是你的用途

backgroundWorker1.ReportProgress(text.Length);

这也没用。你也可以拥有一个

int textLength = 0

然后设置

textLength += line.Length

没有所有的文本操作。

你应该知道这一点。性能问题?永远不要假设,我们总是有一个分析器——它会非常迅速地向你展示问题。这是基本调试。

一些背景数学,顺便说一句:

(对于 500mb 到 1gb 左右的文件)

这意味着,一旦您加载 500mb 的数据,您的代码就会将 500mb(如果文件是 unicode)复制到 1gb(字符串是 ascii 文件大小的两倍),每行复制操作。

您可能需要查看计算机的内存速度。取决于服务器等,您可能会被限制为每秒 50gb(高端 X99 - 较新的 DDR 4 内存更快,但工作站通常具有更少的通道,因此再次变慢)并且副本计数加倍(读取和写入)。这意味着您真的开始遇到“复制字符串会使它们的内存总线超载”的情况。

【讨论】:

    【解决方案3】:

    你可以使用这条线:

    string text = System.IO.File.ReadAllText(file);
    

    【讨论】:

    • 是的,但是这样做时没有办法报告进度(看起来这对 OP 很重要 - 然后可能不是)。
    • 另外,如果他正在处理大文件,他可能不想一次将它们全部读入内存(他在问题中确实提到了 1GB 文件)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-17
    相关资源
    最近更新 更多