C# 中使用HttpClient读取大型Json数据集
問題:如何使用HTTP讀取大型JSON數據?
在工作中我們經常需要調用api獲取數據,這些數據大多數情況下都小型的,比如分頁獲取數據等。通常不使用HTTP方式傳輸大型數據。
然而再最近的一工作中,需要調用[Salesforce] 的api傳輸數據,經過測試發現這個api返回巨量數據,大約50k+,一次性存儲和反序列化這沒多的JSON數據是不可可能的。
方法1:使用傳統一次性讀并反序列化。
所以最快能想到的方法是使用api提供的filter條件減少每次加載的數據大小,然后分批加載他們。示例代碼如下:(為了演示代碼做了簡化)
public class Main {public async void Main(){string year="FY22"; //按年度string accountIds = "123,124"; //按客戶Idvar data = await LoadApiData();JavaScriptSerializer serializer = new JavaScriptSerializer();serializer.DeserializeObject(data);//這是一個老式的方法(新方法使用String.Text.Json),僅用于演示目的。這個反序列化過程如果返回的JSON數據特別大,會超過長度限制而報錯,同時占用內存非常高。}public async Task<string> LoadApiData(string year,string accountIds){string apiUrl = "http://salesforce/api?Year={year}&accountId={accountIds}";HttpClient client = new HttpClient();string jsonResponse = await client.GetStringAsync(apiUrl)return jason} }但最后發現數據量依然很大,這種方法再Javascript反序列化時候會導致超過最大長度限制,內存占用大,最終導致運行失敗。后來嘗試使用更更多的filter去減少返回的數據量,但發現如果這樣寫,太多的參數導致程序的可維護性會變差,同時你也不能保證返回的數據量是否依然超過限制。
經過研究Salesforce的api發現,他們使用了HTTP協議中的流式傳輸,以分塊傳輸的大型Json數據。返回的HTTP頭部包含Transfer-Encoding:chunk。
這樣一來,我們也可以使用HttpClient的流式處理方式來處理返回的數據了,避免了之前的問題,內存占用量也會大大減少。
方法2:使用流式分塊讀取
//該方法使用了C# 8.0的 ? IAsyncEnumerable 異步流接口,后面有機會再跟大家解釋這個強大的功能。 //這里的作用就是為了異步返回流式讀取到的JSON數據。 public async IAsyncEnumerable<string> LoadApiData(string year,string accountIds){string apiUrl = "http://salesforce/api?Year={year}&accountId={accountIds}";HttpClient client = new HttpClient();string jsonResponse = await client.GetStreamAsync(apiUrl); //獲取響應流,該方法會很快返回。因為HTTP一旦準備好頭部就會返回,不會等待所有數據完成后在返回。var reader = new StreamReader(jsonResponse);var jr = new JsonTextReader(reader); //Newtonsoft JSON讀取器,它解決了JSON數組流式返回需要分析json格式的問題。while(jr.Read()){var item = serializer.Deserialize<DataModel>(jr);yield return item;}}//再main方法使用這個異步流返回的結果 public async void Main() {string year="FY22"; //按年度string accountIds = "123,124"; //按客戶Idawait foreach(var item in LoadApiData(year,accountIds)){//處理item。} }總結
我們通常只認為HTTP之傳輸少量的數據,但是HTTP 1.1規范中定了可以使用Transfer-Encoding:chunk的方式分塊傳輸大量數據。
所以再需要傳輸大量數據的情況下(尤其是做上下游系統數據集成分析類應用時)可以使用HTTP流式傳輸,并流式加載和處理他們。好處是占用內存資源大大減少,并可以處理大量數據傳輸。
總結
以上是生活随笔為你收集整理的C# 中使用HttpClient读取大型Json数据集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# Dispose模式
- 下一篇: c# char unsigned_dll