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流式传输,并流式加载和处理他们。好处是占用内存资源大大减少,并可以处理大量数据传输。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

判断质数5个程序

1、 #include <stdio.h>int main(){ int i,no; unsigned long counter0; for(no2;no<1000;no) { for(i2;i<no;i) { counter; if(no%i0) break; } if(no i) printf("%d\n",no); } printf("乘除运算的次数&#xff1a;%lu\n",counter); return…

linux笔记 3-4 SMTP,.配置电子邮件传输

***************4.配置电子邮件传输*****************##1.基本电子邮件配置##配置dns服务&#xff0c;添加MX记录两台服务器分别配置 /etc/postfix/main.cf文件myhostname--主机名mydomain--域名myorigin--重写本地发布的电子邮件,使其显示为来自该域。这样有助于确保响应返回入…

希尔排序算法的实现

希尔排序(Shell Sort)是插入排序的一种&#xff0c;它是针对直接插入排序算法的改进。该方法又称缩小增量排序&#xff0c;因DL&#xff0e;Shell于1959年提出而得名。 希尔排序实质上是一种分组插入方法。它的基本思想是&#xff1a;对于n个待排序的数列&#xff0c;取一个小于…

linux c之信号signal处理机制

最近同事的程序设计过程中用到了Linux的signal机制&#xff0c;从而引发了我对Linux中signal机制的思考。Signal机制在Linux中是一个非常常用的进程间通信机制&#xff0c;很多人在使用的时候不会考虑该机制是具体如何实现的。signal机制可以被理解成进程的软中断&#xff0c;因…

python不能分配给操作员_Python:无法分配给li

运算符的左侧需要是变量。你在这里做的是告诉python&#xff1a;“你知道第一个吗&#xff1f;将其设置为输入的字符串。“。1是文字数字&#xff0c;而不是变量。1总是1&#xff0c;您不能将其“设置”为其他值。变量就像一个可以存储值的框。1是可以存储在变量中的值。input调…

技术分享 | 微服务模式下如何高效进行API测试

导读&#xff1a;微服务架构下&#xff0c;API 测试的最大挑战来自于庞大的测试用例数量&#xff0c;以及微服务之间的相互耦合。基于这种挑战&#xff0c;如何进行高效的API测试&#xff0c;选择什么样的方式就比较重要&#xff0c;此文主要是采用契约测试的方法来对微服务模式…

由CloudStack项目引起的ESXI嵌套虚拟化引起的二级虚拟机无法被访问

关于这个问题&#xff0c;主要以文字描述为主&#xff0c;最终解决方法其实就一个步骤。问题描述&#xff1a;某客户需要部署某企业的云平台&#xff0c;但是由于年前没有足够的物理机资源&#xff0c;所以提供的资源均为虚拟机&#xff0c;现在让我们做技术评估。其实观察整个…

美女的床真的好难爬......

1 地中海式茂密&#xff1f;▼2 阴着呐▼3 拜拜了您呐▼4 草莓从哪里来▼5 爷青结系列▼6 没点才艺还住不了酒店了▼7 美女的床果真很难爬(真从500平大床中醒来)▼8 数学能有多有趣▼你点的每个赞&#xff0c;我都认真当成了喜欢

控制器方法错误处理

错误处理一直是开发维护阶段需要重点关注的一块&#xff0c;控制器中方法原则上都需要处理错误。 1、添加BaseController 路径&#xff1a;nweb\src\main\java\com\nankang\cati\nweb\controller\BaseController.java 所有的控制器都继承BaseController 2、使用&#xff1a; 1&…

linux最常用的20条命令

玩过Linux的人都会知道&#xff0c;Linux中的命令的确是非常多&#xff0c;但是玩过Linux的人也从来不会因为Linux的命令如此之多而烦恼&#xff0c;因为我们只需要掌握我们最常用的命令就可以了。当然你也可以在使用时去找一下man&#xff0c;他会帮你解决不少的问题。然而每个…

linux之od命令总结

od命令用于输出文件的八进制、十六进制或其它格式编码的字节,通常用于显示或查看文件中不能直接显示在终端的字符。常见的文件为文本文件和二进制文件。此命令主要用来查看保存在二进制文件中的值。比如,程序可能输出大量的数据记录,每个数据是一个单精度浮点数。这些数据记…

EF Core 6 新功能汇总(一)

在这篇文章中&#xff0c;你将看到 EF Core 6 中的十个新功能&#xff0c;包括新的特性标注&#xff0c;对时态表、稀疏列的支持&#xff0c;以及其他新功能。1Unicode 特性在 EF Core 6.0 中&#xff0c;新的 UnicodeAttribute 允许你将一个字符串属性映射到一个非 Unicode 列…

swift string转int_swift中结构体和类的区别(值类型和引用类型的区别)

在swift中结构体和类有着更多的相同之处&#xff0c;在一般的使用中能够做到互相替换。我们可以先看看官方文档的描述&#xff1a;Unlike other programming languages, Swift doesn’t require you to create separate interface and implementation files for custom structu…

DS5020配置集群存储

一、方案设计 计划给某公司服务器制作集群&#xff0c;存储划分大致如下&#xff1a; 1、 将存储磁盘制作为raid5&#xff1b; 2、 划分两个Storage Partition给两类集群使用&#xff0c;一类为数据库服务&#xff0c;一类为各种应用服务 二、存储的连接 1、存储的简介 Serial …

RequireJS首次加载偶尔失败

现象&#xff1a;第一次加载JS文件&#xff0c;首次加载偶尔失败&#xff1b; 原因&#xff1a;require([jquery, operamasks, zTree, jQueryCookie]&#xff0c;中前后引用同步加载&#xff1b; 解决方式&#xff1a;shim声明前置加载&#xff1b; 配置如下&#xff1a; requi…

linux之file命令总结

解释&#xff1a; file是通过查看文件的头部内容&#xff0c;来获取文件的类型使用file命令可以知道某个文件究竟是二进制&#xff08;ELF格式&#xff09;的可执行文件, 还是Shell Script文件&#xff0c;或者是其它的什么格式。 file能识别的文件类型&#xff1a;目录、Shel…

优化.NET 应用程序 CPU 和内存的11 个实践

https://michaelscodingspot.com/cpu-bound-memory-bound/优化.NET 应用程序 CPU 和内存的11 个实践凡事都有其限度&#xff0c;对吧&#xff1f;汽车只能开这么快&#xff0c;进程只能使用这么多内存&#xff0c;程序员只能喝这么多咖啡。我们的生产力受到资源的限制&#xff…

陈省身:三角形内角和不等于180°

全世界只有3.14 % 的人关注了爆炸吧知识三角形外角和为360作为公认的劳模&#xff0c;平日里&#xff0c;超模君不但要码字&#xff0c;工作之余还要监督表妹做作业&#xff0c;也难怪表妹成绩总是能名列前茅。今天表妹做作业时&#xff0c;遇到一道判断题&#xff1a;“三角形…