想象一下,我有一个用于编辑文本文件的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);
这些选项的性能考虑因素是什么?
在我看来,无论是逐行读取还是一次读取整个文件,都将读取相同数量的数据,而磁盘时间将占据内存分配时间.就是说,一旦文件在内存中,操作系统就可以*地将其分页回去,并且这样做时,已经失去了进行大量读取的好处.另一方面,在使用临时文件时,一旦关闭句柄,我需要删除旧文件并重命名临时文件,这会产生成本.
然后是有关缓存,预取和磁盘缓冲区大小的问题…
我假设在某些情况下,对文件进行细化比较好,而在其他情况下,按行进行操作则更好.我的问题是,这两种情况的条件是什么?
解决方法:
in some cases, slurping the file is better, and in others, operating by line is better.
非常接近除了逐行阅读实际上是一个更具体的情况.我们要区分的实际选择是ReadAll和使用缓冲区. ReadLine进行假设-最大的假设是该文件实际上具有行,并且它们的长度合理!如果我们无法对文件进行这种假设,则无论是否到达行尾,我们都希望选择一个特定的缓冲区大小并将其读入.
因此,在一次读取所有内容并使用一个缓冲区之间做出决定-始终采用最容易实现且最幼稚的方法,直到遇到无法解决的特定情况-并有一个具体的案例,可以使自己受过良好教育根据您实际拥有的信息做出决定,而不是推测假设情况.
最简单-一次阅读所有内容.
性能成为问题吗?此应用程序是否针对不受控制的文件运行,因此其大小不可预测?只是一些您想对其进行分块的示例.