【发布时间】:2010-09-28 20:29:32
【问题描述】:
我在尝试通过 StreamReader 将 800MB 文本文件加载到 DataTable 时遇到了 OutOfMemory 异常。我想知道是否有办法从内存流中批量加载 DataTable,即从 StreamReader 读取文本文件的前 10,000 行,创建 DataTable,使用 DataTable 执行某些操作,然后将接下来的 10,000 行加载到 StreamReader 和很快。
我的谷歌在这里不是很有帮助,但似乎应该有一个简单的方法来做到这一点。最终,我将使用 SqlBulkCopy 将 DataTables 写入 MS SQL 数据库,因此如果有比我所描述的更简单的方法,我将感谢您提供正确方向的快速指针。
编辑 - 这是我正在运行的代码:
public static DataTable PopulateDataTableFromText(DataTable dt, string txtSource)
{
StreamReader sr = new StreamReader(txtSource);
DataRow dr;
int dtCount = dt.Columns.Count;
string input;
int i = 0;
while ((input = sr.ReadLine()) != null)
{
try
{
string[] stringRows = input.Split(new char[] { '\t' });
dr = dt.NewRow();
for (int a = 0; a < dtCount; a++)
{
string dataType = dt.Columns[a].DataType.ToString();
if (stringRows[a] == "" && (dataType == "System.Int32" || dataType == "System.Int64"))
{
stringRows[a] = "0";
}
dr[a] = Convert.ChangeType(stringRows[a], dt.Columns[a].DataType);
}
dt.Rows.Add(dr);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
i++;
}
return dt;
}
这是返回的错误:
“System.OutOfMemoryException:引发了“System.OutOfMemoryException”类型的异常。
在 System.String.Split(Char[] 分隔符,Int32 计数,StringSplitOptions 选项)
在 System.String.Split(Char[] 分隔符}
在 Harvester.Config.PopulateDataTableFromText(DataTable dt, String txtSource) in C:...."
关于将数据直接加载到 SQL 中的建议 - 我对 C# 有点陌生,但我认为这基本上就是我正在做的事情? SqlBulkCopy.WriteToServer 获取我从文本文件创建的 DataTable 并将其导入 sql。有没有我想念的更简单的方法来做到这一点?
编辑:哦,我忘了提 - 此代码不会与 SQL Server 在同一台服务器上运行。数据文本文件在服务器 B 上,需要写入服务器 A 中的表。这是否排除了使用 bcp?
【问题讨论】:
-
你真的需要一次在内存中保存全部内容吗?
-
我不太确定问题出在哪里。 Streamreader 不会将整个流内容加载到内存中。应该没有什么可以阻止您从 StreamReader 读取流的一部分,进行处理然后加载下一部分等等。您能否展示代码的相关部分,以便我们提供更多帮助?
标签: c# streamreader