我真的希望有人可以帮助我。
我必须将近400,000条记录从数据库传递到文本文件 由于这个数量,文本文件的扩展只是一些东西 我编造了...(。you_name_it) 将数据写入+/- 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);
}
答案 0 :(得分:6)
为什么代码中有这一行?
exportlines += ex.ExportLine() + "\n"
假设它是一个字符串变量,它会增长,增长和增长......并消耗内存。
答案 1 :(得分:0)
您是如何从数据库中读取记录的?如果您正在使用RecordSet,则可以单独处理每条记录,而不是将它们全部存入内存(ExportList())。
答案 2 :(得分:0)
当增长exportlines
(我假设它是一个字符串)时,它会占用的内存量增加一倍(原始值+带有附加值的新值)。 StringBuilder将遇到同样的问题,只有当缓冲区已满时,才会出现每个添加的字符串。
如果要记录写入流的字符串,可以创建一个List并将每行添加到列表中。所以你不需要(至少)加倍所需的存储空间。
但是如果字符串的数量很高,你可以从中得到多少额外的信息?这太过分了。
另外,为什么每次都要刷新流?
答案 3 :(得分:0)
除了上面讨论的字符串增长,而不是ExportList()返回List(Of Export),你可以让它返回IEnumerable(Of Export)并做类似的事情:
private IEnumerable<Export> ExportList() {
foreach (Export ex in whateveryouaredoing) {
yield return ex;
}
}
关键是“收益率退出”。我假设你正在循环一些其他集合并用这些Export对象填充List然后返回整个列表。在许多情况下,您可以使用yield return方法将ExportList方法转换为迭代器,从而一次将内存消耗限制为单个记录的内存消耗。每次遇到yield时,它基本上会运行循环体,因此一次只需要使用一个Export对象。