json格式数据是前后端传输最常用的,一般也不会太大,所以一般也不会存在特殊处理的问题。当遇到较大的,比如超过200M,好家伙,这种级别把记事本程序都能撑爆趴窝,程序运行“一蛇吞象”也立即就有了问题,最常见的应该就是内存溢出bug,笔者就很不幸遇到了,当时真是一脸懵,完全不知所措,而甲方爸爸又催着要产品尽快上线,真是让人捉急。后来查了不少资料才最终搞定。想来还是有一定的借鉴意义的,故将问题解决过程写下来,以供诸君参考。
一、问题描述
我这个是用C#Webservice做后台服务,前端axios调用。主要有三个问题,其一,json格式数据拼接使用Newtonsoft.Json.JsonConvert.SerializeObject(obj)
是不行的,需要改用Newtonsoft.Json.JsonWriter 流读写的方式。其二,json格式的结果数据不能赋值给一个string变量,也不能放到缓存流里,因为都会导致内存溢出,解决方法是将结果先写入存到一个缓存文件里。其三,由于前面两个的问题,后台返回数据方法:this.Context.Response.Write(JsonStr)
也不能用,要改用文件流的形式返回结果。要做脱敏处理,太麻烦,图片就不上传了。下面直接看代码怎么改写。
二、上代码(仅核心部分,其他没啥用,还敏感)
第一部分:Newtonsoft.Json.JsonWriter 流处理json串
System.Data.DataTable dt =DB_Object.ExecDataTable(sql);//数据库中获取数据集合
if (dt != null && dt.Rows.Count > 0)
{
string tempFile = System.IO.Path.GetTempFileName();//创建临时文件 用于存储超大JSON包
System.IO.StreamWriter sw = new System.IO.StreamWriter(tempFile);
using (Newtonsoft.Json.JsonWriter jsonWriter = new Newtonsoft.Json.JsonTextWriter(sw))
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("code");
jsonWriter.WriteValue(200);
jsonWriter.WritePropertyName("msg");
jsonWriter.WriteValue("获取导出数据成功!");
jsonWriter.WritePropertyName("data");
jsonWriter.WriteStartArray();
for (int j = 0; j < dt.Rows.Count; j++)
{
jsonWriter.WriteStartObject();
jsonWriter.WritePropertyName("id");
jsonWriter.WriteValue(dt.Rows[j]["id"].ToString());
。。。
。。。
}
jsonWriter.WriteEndObject();
}
jsonWriter.WriteEndArray();
jsonWriter.WriteEndObject();
jsonWriter.Flush();
}
第二部分:数据包返回给前端
this.Context.Response.ContentType = "application/octet-stream";
this.Context.Response.TransmitFile(tempFile); //该方法不占用内存 防止文件太大导致内存溢出
this.Context.Response.Flush();
System.IO.File.Delete(tempFile);//删除临时文件
最后
至此,问题也就解决了。回头看起来也不难,只是以前没有遇到过,所以一时间还是挺有些棘手。主要还是经验不够吧。到此结束,撒花散了吧!