至少3GB数据的{HttpWebRequest或HttpWebClient

时间:2017-06-30 14:41:48

标签: c# sql-server api

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

string data = client.DownloadString(siteUrl) nor
string data = readStream.ReadToEnd()

我们想出了一个查询参数,它将按区域过滤数据,但如果某个区域超过2GB的数据,这也会失败。那么有什么其他方法可以从API URL获取整个数据块吗?

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

string data = client.DownloadString(siteUrl)

然后反序列化数据,这样我就可以在下一步过滤掉我需要的元素。

JsonConvert.DeserializeObject<Dictionary<string, object>>(data)

由于返回的API不仅返回数据列表,因此我需要在应该采用数据的位置定义startElement。

List<Dictionary<string, string>> arrayOfData = (List<Dictionary<string, string>>)(data[startElement] as Newtonsoft.Json.Linq.JArray).ToObject(typeof(List<Dictionary<string, string>>));

我通过arrayOfData.Count迭代以匹配sql中列的映射,然后将其数据存储到List&gt;然后由SQL提供程序将其插入到数据库中。下面是一个示例数据结构(因为实际数据是保密的)

  

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

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

3 个答案:

答案 0 :(得分:0)

改为写入文件。例如

app.config

答案 1 :(得分:0)

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

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

在理想的世界中,如果有可能返回那么多数据,则应该更改API以实现分页。

答案 2 :(得分:0)

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

  

您可以从流中读取块,直到(使用正则表达式)到达分隔符(如},数组中的对象结束),并在读取更多内容之前一次反序列化和处理1(或固定数字)对象。

所以我做了,它有效!对于任何感兴趣的人,以下是步骤:

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

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