StreamReader的性能很差,同时读取非常大的文件

时间:2014-07-04 06:55:47

标签: c# performance io streamreader

我需要在C#应用程序上逐行读取四个非常大(> 2 Gb)的文件同时。我正在使用四种不同的StreamReader对象及其ReadLine()方法。从四个文件同时读取行时,性能受到严重影响,但只要每个文件到达EoF就会变得更好(有4个文件的性能<性能与3个文件< perf有2个文件...)。

我有这个(简化,假设只有两个文件用于更清洁的例子)代码:

StreamReader readerOne = new StreamReader(@"C:\temp\file1.txt");
StreamReader readerTwo = new StreamReader(@"C:\temp\file2.txt");

while(readerOne.Peek() >= 0 || readerTwo.Peek() >= 0)
{
    string[] readerOneFields = readerOne.Peek() >= 0 ? 
        readerOne.ReadLine().Split(',') : null;
    string[] readerTwoFields = readerTwo.Peek() >= 0 ? 
        readerTwo.ReadLine().Split(',') : null;

    if (readerOneFields != null && readerTwoFields != null)
    {
        if (readerOneFields[2] == readerTwoFields[2])
        {
            // Do some boring things...
        }
    else if (readerOneFields != null)
    {
        // ...
    }
    else
    {
        // ...
    }
}
readerOne.Close();
readerTwo.Close();

我必须同时读取这些文件的原因是因为我需要做一些比较这些行的东西,然后将结果写入新文件。

我已经阅读了很多关于使用StreamReader进行大文件读取的问题,但我找不到像我这样的场景。它正在使用ReadLine()方法来实现这一目标的正确方法?它甚至是StreamReader正确的类吗?

更新:现在事情变得更加棘手了。仅仅是为了测试我试图通过删除行来减小文件大小到大约10 Mb,只留下70K记录。此外,我曾尝试同时只使用两个文件(而不是四个)。而且我同时从这两个文件中读取时,同样表现不佳!当其中一个人达到EoF时,性能会变得更好。我将StreamReader缓冲区大小设置为50 MB。

1 个答案:

答案 0 :(得分:8)

到目前为止,你用磁盘做的最昂贵的事情就是强迫读卡器头从一个磁道移动到另一个磁道。这是一种机械运动,每道的典型成本约为13毫秒。

您正在移动读取器头,不断地从一个文件到另一个文件来回移动。需要缓冲来降低成本,换句话说,从一个文件中读取大量数据。操作系统已经进行了一些缓冲,它从文件中读取了一个跟踪数据的数据。你需要更多。

使用允许您指定缓冲区大小的StreamReader constructors之一。对于这么大的文件,缓冲区大小为50兆字节是合适的。