C# 至少3GB数据上的HttpWebRequest或HttpWebClient

C# 至少3GB数据上的HttpWebRequest或HttpWebClient,c#,sql-server,api,C#,Sql Server,Api,我试图从一个包含至少3GB数据的API URL获取数据(因为这是企业级的),并将其插入SQL Server中的表中。我收到一个错误“内存不足,无法继续执行程序”。我知道一个字符串最多只能包含2GB的数据,这就是为什么以下操作不起作用的原因: string data = client.DownloadString(siteUrl) nor string data = readStream.ReadToEnd() 我们提出了一个想法,即使用一个查询参数来按区域过滤数据,但如果某个区域的数据超过2G

我试图从一个包含至少3GB数据的API URL获取数据(因为这是企业级的),并将其插入SQL Server中的表中。我收到一个错误“内存不足,无法继续执行程序”。我知道一个字符串最多只能包含2GB的数据,这就是为什么以下操作不起作用的原因:

string data = client.DownloadString(siteUrl) nor
string data = readStream.ReadToEnd()
我们提出了一个想法,即使用一个查询参数来按区域过滤数据,但如果某个区域的数据超过2GB,该参数也会失败。那么,有没有其他方法可以从API URL获取整个数据块

编辑 我们目前拥有的是将数据从存储到C#中的字符串对象

然后反序列化数据,以便在下一步中过滤出所需的元素

JsonConvert.DeserializeObject<Dictionary<string, object>>(data)
JsonConvert.DeserializeObject(数据)
由于返回的API不只是返回数据列表,因此我需要定义一个startElement,说明应该在哪里获取数据

List<Dictionary<string, string>> arrayOfData = (List<Dictionary<string, string>>)(data[startElement] as Newtonsoft.Json.Linq.JArray).ToObject(typeof(List<Dictionary<string, string>>));
List arrayOfData=(List)(数据[startElement]为Newtonsoft.Json.Linq.JArray).ToObject(typeof(List));
我通过arrayOfData.Count进行迭代,以匹配sql中列的映射及其数据,然后将其存储到列表>,然后由sql提供程序将其插入数据库。下面是一个示例数据结构(因为实际数据是保密的)

{“href”:“someUrl”,“limit”:“1”,“records”:[{“columnA”:“1”,“columnB”:“2”,“columnC”:“3”}]}


问题是,我无法进行处理,因为3GB的数据太多,字符串无法处理,因此我想问是否有其他存储方式(我知道我可以将其存储在文件中,但数据使其难以按原样插入)。

改为写入文件。乙二醇

using (var file = File.OpenWrite(@"c:\temp\foo.dat"))
{
    readStream.CopyTo(file);
}

如果您可以在64操作系统上运行并使用.NET 4.5或更高版本,则此应用程序设置将提高2G的内存限制

<runtime>
    <gcAllowVeryLargeObjects enabled="true" />    
</runtime>


在理想情况下,如果API有可能返回那么多数据,则应更改API以实现分页。

正如Igor在评论中建议的那样:

您可以从流中读取数据块,直到(使用正则表达式)到达一个清除器(如},数组中对象的末尾),然后在读取更多数据之前反序列化并一次处理1个(或固定数量)对象

所以我做到了,而且成功了!对于任何感兴趣的人,以下是步骤:

  • 将数据下载到文件
    client.DownloadString(siteUrl)
    ,而不是将大块数据存储到字符串
    client.DownloadFile(siteUrl,“data.json”)
  • 使用StreamReader从文件
    中读取每个字符,使用(StreamReader sr=new StreamReader(@“E:Debug\data.json”)
  • 创建了一个方法,该方法将从下载的文件中读取每个字符,并在遇到“[”时开始存储它
  • 将每个字符存储到
    列表中
    并创建一个新字符串
    新字符串(chars.ToArray())
    如果它碰到“}”-请注意,1“{}”相当于1条有效记录
  • JSON使用
    JsonConvert.DeserializeObject(记录)
  • 将数据映射到SQL Server表中插入数据的每一列
  • 插入数据后清除
    列表
    ,以处理下一条记录

在这个过程中,一次只存储一条记录。它可以工作,但需要很长时间才能完成。请告诉我是否有更好的方法来处理这个问题!

您需要处理流。不要调用
ReadToEnd
@NtFreX,但是我如何解析数据以将其插入到表中?您可以控制API吗?关系数据库是mEnter要存储关系数据,这是他们擅长的。他们不好的是存储大的非结构化数据集。你应该考虑一种不同的方法来存储3GB的非结构化数据。一个好的和常用的替代方法是将数据存储在文件系统上,并在数据库中存储一个指向该文件的指针。如果必须存储数据。在数据库中考虑使用。结果结构是一个数组,是结构FixEx?您可以从流中读取块(直到使用正则表达式)到达一个分隔符(如<代码> },< /代码>数组中的对象结束),并反序列化和处理1(或固定数)。对象。这是从流中读取数据的唯一其他方法。您没有明确说明将对结果执行什么操作。很抱歉,我刚刚编辑了我的问题。我知道我可以将数据保存为文件,但我的问题是如何解析数据并插入sql server中的表,因为我无法存储它位于C#中的一个对象中。只需开始从流中读取、解析记录并加载SQL Server。您将希望使用SqlBulkCopy加载那么多数据。谢谢您,但我认为这对我的问题不起作用。我在问题中添加了一个编辑部分。让我尝试一下!效果如何?谢谢您,但不幸的是,它没有我发布了一个对我有用的答案,这是Igor在评论中提出的。
<runtime>
    <gcAllowVeryLargeObjects enabled="true" />    
</runtime>