2

我要求连接超过 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);
        }
    }
}
4

2 回答 2

7

CopyTo 将复制块(4096 = 默认大小),ReadToEnd 将在写入之前读取所有数据。因此,使用 ReadToEnd() 方法将完全读取 1gb 文件。所以对于大文件,我会建议 CopyTo。

CopyTo 有一个重载方法来指定块大小。

Stream.CopyTo 方法(流,Int32)http://msdn.microsoft.com/en-us/library/dd783870.aspx

于 2013-08-13T19:01:34.437 回答
3

Stream.CopyTo以块的形式复制数据。(Stream, int) 重载允许您指定缓冲区的大小,但默认为 4096 字节。

TextReader.ReadToEnd会将整个文件读入内存,因此在这种情况下,Stream.CopyTo内存效率会更高。

于 2013-08-13T19:03:26.810 回答