C#序列化大数据对象时JSON不完整且速度慢的问题求助
问题解决:大数据集序列化慢+FTP上传JSON不完整
问题根源
- 同步将大数据集序列化为字符串,会占用大量内存,导致序列化耗时久,同时大字符串转流时易出现隐性截断。
- 转成流后未重置流的起始位置,FTP上传时从流的当前位置开始读取,直接导致内容不完整。
优化方案
1. 异步直接序列化到流(核心修复)
跳过中间字符串环节,直接将对象异步序列化到流中,既减少内存占用,又提升序列化速度,同时避免字符串带来的截断问题:
var fileUploadPath = _kubotaHistoryOptions?.RootPath + getKubotaInvoiceHistoryFileName(location.Item1); using var stream = new MemoryStream(); // 异步序列化到流 await JsonSerializer.SerializeAsync(stream, warrantyData.WorkOrders); // 重置流位置到开头,确保FTP能读取完整内容 stream.Position = 0; await _iFtpClientService.SendFileAsync(_kubotaHistoryOptions?.FTP, stream, fileUploadPath);
2. 序列化配置优化
通过调整序列化选项进一步提升速度、缩小文件体积:
var serializeOptions = new JsonSerializerOptions { WriteIndented = false, // 关闭缩进,减少序列化时间和文件大小 IgnoreNullValues = true, // 忽略空值属性,精简输出内容 }; await JsonSerializer.SerializeAsync(stream, warrantyData.WorkOrders, serializeOptions);
3. 超大数据集的内存优化
如果数据集极大,内存流仍会占用过多内存,可先序列化到本地临时文件,再上传:
var tempFilePath = Path.GetTempFileName(); try { // 序列化到本地临时文件 using var writeStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write); await JsonSerializer.SerializeAsync(writeStream, warrantyData.WorkOrders); // 读取临时文件并上传 using var readStream = new FileStream(tempFilePath, FileMode.Open, FileAccess.Read); await _iFtpClientService.SendFileAsync(_kubotaHistoryOptions?.FTP, readStream, fileUploadPath); } finally { // 上传完成后删除临时文件 if (File.Exists(tempFilePath)) File.Delete(tempFilePath); }
4. 检查FTP上传逻辑
确认SendFileAsync方法能完整读取流至末尾,避免因FTP客户端实现问题导致的内容截断。
内容的提问来源于stack exchange,提问作者Kamran Khan
相关产品推荐
相关产品推荐

