gpt4 book ai didi

c# - 从 StreamReader 中批量读取

转载 作者:太空狗 更新时间:2023-10-30 00:21:48 25 4
gpt4 key购买 nike

我在尝试通过 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: Exception of type 'System.OutOfMemoryException' was thrown.
at System.String.Split(Char[] separator, Int32 count, StringSplitOptions options)
at System.String.Split(Char[] separator}
at Harvester.Config.PopulateDataTableFromText(DataTable dt, String txtSource) in C:...."

关于将数据直接加载到 SQL 中的建议——我对 C# 有点菜鸟,但我认为这基本上就是我在做的事情? SqlBulkCopy.WriteToServer 获取我从文本文件创建的 DataTable 并将其导入到 sql 中。有没有更简单的方法来做到这一点,我错过了?

编辑:哦,我忘了说 - 这段代码不会在与 SQL Server 相同的服务器上运行。数据文本文件在服务器 B 上,需要写入服务器 A 中的表。这是否排除了使用 bcp?

最佳答案

您是否考虑过将数据直接加载到 SQL Server 中,然后在数据库中对其进行操作?数据库引擎已经设计为可以高效地操作大量数据。这可能会产生更好的整体结果,并允许您利用数据库和 SQL 语言的功能来完成繁重的工作。这是古老的“更聪明地工作而不是更努力地工作”原则。

有很多 different methods to load data into SQL Server ,因此您可能需要检查这些以查看是否合适。如果您使用的是 SQLServer 2005 或更高版本,并且确实需要在 C# 中对数据进行一些操作,则始终可以使用 managed stored procedure .

这里要意识到 OutOfMemoryException 有点误导。 Memory is more than just the amount of physical RAM you have .您可能用完的是可寻址内存。这是非常不同的事情。

当您将一个大文件加载到内存中并将其转换为 DataTable 时,它可能需要远远超过 800Mb 来表示相同的数据。自 32 位 .NET 以来进程被限制为不到 2Gb 的可寻址内存,您可能永远无法在单个批处理中处理如此数量的数据。

您可能需要做的是以流方式处理数据。换句话说,不要尝试将其全部加载到 DataTable 中,并且然后批量插入到 SQLServer。而是分块处理文件,在完成处理后清除先前的行集。

现在,如果您可以访问具有大量内存(以避免 VM 抖动)的 64 位计算机并且64 位 .NET 运行时的副本,您可能可以在运行代码时保持不变。但我建议无论如何都要进行必要的更改,因为即使在那种环境下,它也可能会提高性能。

关于c# - 从 StreamReader 中批量读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3816789/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com