Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/238.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何高效地用C#编写大型文本文件?_C#_Text Files_Io - Fatal编程技术网

如何高效地用C#编写大型文本文件?

如何高效地用C#编写大型文本文件?,c#,text-files,io,C#,Text Files,Io,我正在用C#创建一个方法,为一个文件生成一个文本文件。提要将包含30000条以上的记录,文本文件目前的重量约为7Mb 以下是我当前使用的代码(为了简洁起见,删除了一些行) 我想知道StringBuilder是否适合这项工作。如果我改用TextWriter,性能会有所提高吗 我对IO性能一窍不通,因此如有任何帮助或总体改进,将不胜感激。谢谢。使用StreamWriter一次编写一个字符串。编写而不是在StringBuilder中缓存所有内容。只需使用语句移动,使其包含整个代码,然后直接写入文件。我

我正在用C#创建一个方法,为一个文件生成一个文本文件。提要将包含30000条以上的记录,文本文件目前的重量约为7Mb

以下是我当前使用的代码(为了简洁起见,删除了一些行)

我想知道StringBuilder是否适合这项工作。如果我改用TextWriter,性能会有所提高吗


我对IO性能一窍不通,因此如有任何帮助或总体改进,将不胜感激。谢谢。

使用StreamWriter一次编写一个字符串。编写而不是在StringBuilder中缓存所有内容。

只需使用
语句移动
,使其包含整个代码,然后直接写入文件。我认为没有必要先把它全部保存在内存中。

文件I/O操作在现代操作系统中通常得到了很好的优化。您不应该尝试将文件的整个字符串组合到内存中。。。把它一件一件地写出来。
FileStream
将考虑缓冲和其他性能因素

您可以通过移动以下内容轻松进行此更改:

using (StreamWriter outfile = new StreamWriter(filePath)) {
到函数的顶部,并摆脱直接写入文件的
StringBuilder

避免在内存中建立大字符串有几个原因:

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

  • 这可能很旧,但我有一个文件要写,大约1700万行 因此,我最终每10k行批处理一次写操作,类似于这些行

    for (i6 = 1; i6 <= ball; i6++) 
    { //this is middle of 6 deep nest ..
      counter++;
      // modus to get a value at every so often 10k lines
      divtrue = counter % 10000; // remainder operator % for 10k
      //  build the string of fields with \n at the end 
      lineout = lineout + whatever 
      // the magic 10k block here
      if (divtrue.Equals(0))  
      {
         using (StreamWriter outFile = new StreamWriter(@filepath, true))
         { 
             //  write the 10k lines with .write NOT writeline..
             outFile.Write(lineout); 
         } 
         // reset the string so we dont do silly like memory overflow
         lineout = ""; 
      }
    }
    

    用于(i6=1;i6我真的希望你不是想让他一次写一点。虽然这是一个很好的答案。我有一个大约20Mb大小的文件,我面临的问题是StreamWriter实际上在末尾放了一个回车符/新行。我正试图在最后删除多余的回车符,正如已经指出的那样StringBuilder在性能和大小方面都不是一个很好的解决方案。我尝试了StreamReader.Peek()在它结束之前查看这一行。有什么想法吗?@MaximusMeters您可能在这期间找到了自己的方法,但可能您使用的是
    WriteLine()
    方法而不是
    Write()
    ?回答很好。可以使用StreamWriter构造函数重载来尝试调整,该重载允许您定义缓冲区大小…嘿,感谢您的回答!我感谢您花时间添加关于如何处理此类场景的进一步解释。5年后,
    FileStream
    类仍然是编写tex的最佳方法吗t文件~7MB?自从我写这个问题以来,Linq2Csv项目就开始了。这是处理我正在写的代码的一种更好的方式。有没有完整的源代码和解决方案?对不起,它是为我的一个客户写的。你真的应该看看Linq2Csv。它将使这类事情变得更容易。自从我上次对t的评论以来已经将近5年了对于他的问题,我强烈推荐CsvHelper。
    for (i6 = 1; i6 <= ball; i6++) 
    { //this is middle of 6 deep nest ..
      counter++;
      // modus to get a value at every so often 10k lines
      divtrue = counter % 10000; // remainder operator % for 10k
      //  build the string of fields with \n at the end 
      lineout = lineout + whatever 
      // the magic 10k block here
      if (divtrue.Equals(0))  
      {
         using (StreamWriter outFile = new StreamWriter(@filepath, true))
         { 
             //  write the 10k lines with .write NOT writeline..
             outFile.Write(lineout); 
         } 
         // reset the string so we dont do silly like memory overflow
         lineout = ""; 
      }
    }