StreamReader对于大文件来说非常慢

时间:2016-04-22 08:28:07

标签: c# streamreader

我想读一个文件,在这种情况下是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的文件)

3 个答案:

答案 0 :(得分:5)

使用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());

答案 1 :(得分:4)

  

StreamReader对于大文件C#

非常慢
不,它不是。如果你已经完成了运行探查器的基本功课,你会发现花费的时间不会花在流阅读器上。

  

text + =(line);

这一行正在创建一个新字符串。因为这是必须分配新的内存。对于大文件,这是一个非常大的垃圾创建量。它越长,你做的复制操作就越多。

如果你将它用于

  

backgroundWorker1.ReportProgress(text.Length);

它也没用。你也可以有一个

  

int textLength = 0

然后你设置

  

textLength + = line.Length

没有所有文字操作。

你应该知道这一点。性能问题?永远不要假设,总是让我们成为一名探查者 - 这会非常及时地向您展示这个问题。这是基本的调试。

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

  

(对于大约500mb到1gb的文件)

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

您可能想要查看计算机的内存速度。根据服务器等的不同,您可能会被限制为每秒50gb(高端X99 - 较新的DDR 4存储器速度更快,但工作站通道的通道数量更少,因此速度更慢)并且副本数量增加一倍(读取和写入)。这意味着你真的开始遇到"复制字符串会使内存总线超载#34;场景。

答案 2 :(得分:0)

您可以使用以下行:

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