C# ';System.OutOfMemoryException';将400.000条记录写入文件时

C# ';System.OutOfMemoryException';将400.000条记录写入文件时,c#,C#,我真的很希望有人能帮助我 我必须将近40万条记录从数据库传递到文本文件 由于这个数量,文本文件的扩展名只是一些东西 我编了…(你的名字) 我在将数据写入+/-9000记录的文件时出错。 引发了类型为“System.OutOfMemoryException”的错误=异常 我不知道解决办法:( 这是我用来将记录写入文件的代码的和平 this.path_to_file = ConfigurationManager.AppSettings["ExportDir"] + D

我真的很希望有人能帮助我

我必须将近40万条记录从数据库传递到文本文件 由于这个数量,文本文件的扩展名只是一些东西 我编了…(你的名字) 我在将数据写入+/-9000记录的文件时出错。 引发了类型为“System.OutOfMemoryException”的错误=异常 我不知道解决办法:(

这是我用来将记录写入文件的代码的和平

        this.path_to_file =
        ConfigurationManager.AppSettings["ExportDir"] +
DateTime.Now.ToString(ConfigurationManager.AppSettings
["Export_FileName"]) + ConfigurationManager.AppSettings
["Export_Extension"];


        FileStream fm = new FileStream
           (this.path_to_file, FileMode.Create, FileAccess.ReadWrite,
FileShare.ReadWrite);

        StreamWriter sw = new StreamWriter(fm, Encoding.Default);

        List<Export> exportRecords = null;

        exportRecords = ExportList();
        try
        {
            int i = 0;
           foreach (Export ex in exportRecords)
           {
               sw.Write(ex.ExportLine());
              sw.Write(sw.NewLine);
              sw.Flush();
              exportlines += ex.ExportLine() + "\n";
               i++;
           }
        }
        catch (Exception exc)
        {
           Log.Write(exc.Message);
        }
this.path\u到\u文件=
ConfigurationManager.AppSettings[“ExportDir”]+
DateTime.Now.ToString(ConfigurationManager.AppSettings
[“导出文件名”])+ConfigurationManager.AppSettings
[“出口扩展”];
FileStream fm=新的FileStream
(this.path_to_文件,FileMode.Create,FileAccess.ReadWrite,
FileShare.ReadWrite);
StreamWriter sw=新StreamWriter(fm,Encoding.Default);
List exportRecords=null;
exportRecords=ExportList();
尝试
{
int i=0;
foreach(出口记录中的出口交货)
{
sw.Write(例如ExportLine());
sw.Write(sw.NewLine);
sw.Flush();
ExportLine+=例如ExportLine()+“\n”;
i++;
}
}
捕获(异常exc)
{
日志写入(exc.Message);
}

为什么代码中有这一行

      exportlines += ex.ExportLine() + "\n"

假设它是一个字符串变量,它会不断增长…并消耗内存。

为什么这一行会出现在代码中

      exportlines += ex.ExportLine() + "\n"

假设它是一个字符串变量,它会不断增长…并消耗内存。

如何从数据库中读取记录?如果使用记录集,则可以单独处理每条记录,而不是将它们全部放入内存(ExportList()).

如何从数据库中读取记录?如果使用记录集,则可以单独处理每条记录,而不是将它们全部放入内存(ExportList())。

在增加
导出行时(我假设它是一个字符串),它会使占用的内存量增加一倍(原始值+新值和AppPend值)。StringBuilder也会遇到同样的问题,只是在缓冲区已满的情况下,并不是每个添加的字符串都会遇到同样的问题

如果您想要写入流的字符串记录,可以创建一个列表并将每一行添加到列表中,这样您就不会(至少)加倍所需的存储

但是,如果字符串的数量如此之多,您可以从中获得什么额外的信息呢?这太多了


另外,为什么每次都刷新流?

当增加
导出行时(我假设它是一个字符串),它会使占用的内存量增加一倍(原始值+新值和AppPend值)。StringBuilder会遇到同样的问题,只是不是在添加的每个字符串上,就在缓冲区已满时

如果您想要写入流的字符串记录,可以创建一个列表并将每一行添加到列表中,这样您就不会(至少)加倍所需的存储

但是,如果字符串的数量如此之多,您可以从中获得什么额外的信息呢?这太多了


另外,为什么每次都刷新流?

除了上面讨论的字符串增长之外,您可以使其返回IEnumerable(of Export)并执行以下操作,而不是ExportList()返回列表(of Export):

private IEnumerable<Export> ExportList() {
    foreach (Export ex in whateveryouaredoing) {
        yield return ex;
    }
}
private IEnumerable ExportList(){
foreach(无论您在做什么,均以ex出口){
收益率;
}
}

关键的一行是“收益率回报率”。我假设您正在循环其他一些集合,并使用这些导出对象填充列表,然后返回整个列表。在许多情况下,您可以通过使用收益返回方法将您的ExportList方法转换为迭代器,一次将内存消耗限制为单个记录的内存消耗。它基本上会运行每次遇到yield时循环,因此一次只需要使用一个导出对象。

除了上面讨论的字符串增长之外,您可以使其返回IEnumerable(of Export),而不是ExportList()返回列表(of Export),并执行以下操作:

private IEnumerable<Export> ExportList() {
    foreach (Export ex in whateveryouaredoing) {
        yield return ex;
    }
}
private IEnumerable ExportList(){
foreach(无论您在做什么,均以ex出口){
收益率;
}
}

关键的一行是“收益率回报率”。我假设您正在循环其他一些集合,并使用这些导出对象填充列表,然后返回整个列表。在许多情况下,您可以通过使用收益返回方法将您的ExportList方法转换为迭代器,一次将内存消耗限制为单个记录的内存消耗。它基本上会运行每次遇到产量时循环,因此一次只需要使用一个导出对象。

也许您还应该建议一个解决方案,如StringBuilder。如果它不用于OP中未显示的任何其他内容,则隐含的解决方案是将其取出。嗯,我现在正在尝试,但没有额外的行,也许这会有帮助:)pfff,这就是解决办法。。。THK UPerhaps您还应该建议一个解决方案,例如StringBuilder。如果它不用于OP中未显示的任何其他内容,则隐含的解决方案是将其取出。嗯,我现在正在尝试,但没有多余的行,也许这会有帮助:)pfff,这就是解决方案。。。没有。你应该在最后把它关上,而不是在每一行之后都冲洗它。不,不是。你应该在最后关闭它,而不是在每一行之后冲洗它。