如何有效地写在C#中的大文本文件?

我正在C#中创build一个方法,该方法为Google Product Feed生成文本文件。 Feed将包含超过30,000条logging,文本文件的重量约为7Mb。

这是我目前正在使用的代码(为简洁起见删除了一些行)。

public static void GenerateTextFile(string filePath) { var sb = new StringBuilder(1000); sb.Append("availability").Append("\t"); sb.Append("condition").Append("\t"); sb.Append("description").Append("\t"); // repetitive code hidden for brevity ... sb.Append(Environment.NewLine); var items = inventoryRepo.GetItemsForSale(); foreach (var p in items) { sb.Append("in stock").Append("\t"); sb.Append("used").Append("\t"); sb.Append(p.Description).Append("\t"); // repetitive code hidden for brevity ... sb.AppendLine(); } using (StreamWriter outfile = new StreamWriter(filePath)) { result.Append("Writing text file to disk.").AppendLine(); outfile.Write(sb.ToString()); } } 

我想知道如果StringBuilder是工作的正确工具。 如果我使用TextWriter,会有性能提升吗?

我不知道IO的performance,所以任何帮助或一般的改进,将不胜感激。 谢谢。

文件I / O操作通常在现代操作系统中得到了很好的优化。 你不应该试图把文件的整个string组装到内存中……只要一块一块地写出来。 FileStream将负责缓冲和其他性能方面的考虑。

您可以通过移动来轻松完成此项更改:

 using (StreamWriter outfile = new StreamWriter(filePath)) { 

到函数的顶部,而不是直接将StringBuilder写入文件。

有几个原因可以避免在内存中build立大型string:

  1. 它实际上可能会performance得更差,因为StringBuilder在写入时必须增加容量,导致内存重新分配和复制。
  2. 它可能需要比物理分配更多的内存 – 这可能导致使用比RAM慢得多的虚拟内存(交换文件)。
  3. 对于真正的大文件(> 2Gb),您将耗尽地址空间(在32位平台上),并且将无法完成。
  4. 要将StringBuilder内容写入文件,必须使用ToString() ,这会使进程的内存消耗增加一倍,因为这两个副本必须在内存中一段时间​​。 如果地址空间足够分散,则此操作也可能失败,从而无法分配单个连续的内存块。

只需移动using语句,使其包含整个代码,然后直接写入文件即可。 我认为没有必要先把它全部留在记忆中。

使用StreamWriter.Write一次写入一个string,而不是在StringBuilder中caching所有内容。