什么时候我应该啜饮一个文件,什么时候应该在线阅读?

时间:2010-07-21 01:32:07

标签: c# performance filestream

想象一下,我有一个编辑文本文件的C#应用​​程序。每个文件使用的技术可以是:

1)立即将文件读入字符串,进行更改,并将字符串写在现有文件上:

string fileContents = File.ReadAllText(fileName);

// make changes to fileContents here...

using (StreamWriter writer = new StreamWriter(fileName))
{
    writer.Write(fileContents);
}

2)逐行读取文件,将更改写入临时文件,然后删除源并重命名临时文件:

using (StreamReader reader = new StreamReader(fileName))
{
    string line;

    using (StreamWriter writer = new StreamWriter(fileName + ".tmp"))
    {
        while (!reader.EndOfStream)
        {
            line = reader.ReadLine();
            // make changes to line here
            writer.WriteLine(line);
        }
    }
}
File.Delete(fileName);
File.Move(fileName + ".tmp", fileName);

这些选项的性能考虑因素是什么?

在我看来,无论是直接读取还是一次读取整个文件,都会读取相同数量的数据,磁盘时间将主导内存分配时间。也就是说,一旦文件在内存中,操作系统就可以自由地将其分页,当它这样做时,大量读取的好处就会丢失。另一方面,当使用临时文件时,一旦句柄关闭,我需要删除旧文件并重命名临时文件,这会产生成本。

然后有关于缓存,预取和磁盘缓冲区大小的问题......

我假设在某些情况下,啜饮文件更好,而在其他情况下,按行操作会更好。我的问题是,这两种情况的条件是什么?

1 个答案:

答案 0 :(得分:4)

  

在某些情况下,啜饮文件会更好,而在其他情况下,按行操作会更好。

非常接近;除了逐行阅读实际上是一个更具体的案例。我们想要区分的实际选择是ReadAll和使用缓冲区。 ReadLine做出假设 - 最大的一个是文件实际上有行,而且它们是合理的长度!如果我们不能对文件做出这个假设,我们想要选择一个特定的缓冲区大小并读入它,无论我们是否已到达某一行的末尾。

因此决定一次性阅读所有内容并使用缓冲区 - 始终采用最简单的方法,最简单的方法,直到遇到对您不起作用的特定情况 - 并且有了具体案例,你可以根据你实际拥有的信息作出有根据的决定,而不是推测假设的情况。

最简单 - 一次阅读。

性能成为问题吗?此应用程序是否针对不受控制的文件运行,因此它们的大小是不可预测的?只是举几个例子,你想要把它分块。