我要求连接超过500MB的文本文件。
给我的遗留代码使用TextReader.ReadToEnd(),代码如下:
using (TextWriter textWriter = new StreamWriter(concatenatedFile, false, fEncoding))
{
foreach (string filename in filesToConcatenate)
{
using (TextReader textReader = new StreamReader(filename, Encoding.Default))
{
textWriter.Write(textReader.ReadToEnd());
}
}
}
我想更改上面的代码,将Stream.CopyTo()与File.OpenRead一起使用。 为了证明这种改变的合理性,我可以想到,当ReadToEnd()用于非常大的文件时,我会想到OutofMemoryException。
ReadToEnd()给我的印象是它将读到最后,将整个文本块(在本例中为500MB ??)保存到内存中然后写入指定的流。
所以我的问题是: 在非常大的文件串联中,Stream.CopyTo()的行为与ReadToEnd()的行为有何不同?每次Stream.CopyTo()复制到流中时,将决定文本大小的内容是什么?在大多数情况下,使用它而不是ReadToEnd()会阻止OutOfMemoryException吗?
以下是我想要使用的代码:
using (Stream output = System.IO.File.OpenWrite(outputFile))
{
foreach (string inputFile in inputFiles)
{
using (Stream input = System.IO.File.OpenRead(inputFile))
{
input.CopyTo(output);
}
}
}
答案 0 :(得分:7)
CopyTo将以块(4096 =默认大小)复制,ReadToEnd将在写入之前读取所有数据。因此,使用ReadToEnd()方法将完全读取1gb文件。所以对于大文件,我会建议CopyTo。
CopyTo有一个重载方法来指定blocksize。
Stream.CopyTo方法(Stream,Int32)http://msdn.microsoft.com/en-us/library/dd783870.aspx
答案 1 :(得分:3)
Stream.CopyTo
以块为单位复制数据。 (Stream,int)重载允许您指定缓冲区的大小,但默认值为4096字节。
TextReader.ReadToEnd
会将整个文件读入内存,因此在这种情况下,Stream.CopyTo
将提高内存效率。