[英]Processing large text (JSON) file
我要求允許我的Intranet .NET Web門戶用戶將自由文本SQL查詢發送到后端(SQL Server 2014上的只讀數據庫)並在Excel中獲取結果,盡管在大多數情況下,此方法工作正常,但代碼當結果太大(大約350mb,250k記錄)無法處理時,將失敗。
我的第一次嘗試是將結果直接作為JSON序列化到前端的數據表中。
這失敗了,因為遍歷結果集將拋出System.OutOfMemoryException
:
private JavaScriptSerializer _serializer;
return _serializer.Serialize(results));
因此,決定直接在界面上顯示此結果數量並不是一件好事,因為IE會遇到困難。 因此,選擇了提示用戶通過將結果保存到JSON文件中來下載輸出的Excel副本的選項,然后讀取該文件並將其轉換為Excel:
using (StreamReader sr = new StreamReader(filePath))
String json;
// Read and display lines from the file until the end of
// the file is reached.
while ((json = sr.ReadLine()) != null)
{
Console.WriteLine(json);}
}
但是,ReadLine()方法會引發相同的異常,請注意,由於文件僅包含一行,因此ReadLine失敗,否則我將嘗試逐行進行迭代。
最后,我嘗試直接訪問IEnumerable並將其寫入Excel
var results = new ReportProcess().ExecuteSql(sqlQuery, out string eventMessage);
List<object> queryObjects = new List<object>();
foreach (var result in results)
{
queryObjects.Add(result);
}
var row = queryObjects.FirstOrDefault();
if (row != null)
{
var recordType = row.GetType();
using (var excelFile = new ExcelPackage())
{
MemberInfo[] membersToInclude = recordType
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.ToArray();
var worksheet = excelFile.Workbook.Worksheets.Add("Sheet1");
worksheet.Cells.LoadFromCollection(queryObjects, true,
OfficeOpenXml.Table.TableStyles.None,
BindingFlags.Instance | BindingFlags.Public,
membersToInclude);
fileName = Guid.NewGuid() + ".xlsx";
excelFile.SaveAs(new FileInfo(HttpContext.Current.Server.MapPath("~/temp/") + fileName));
}
}
然后代碼再次失敗
foreach (var result in results)
{
queryObjects.Add(result);
}
一樣的例外
因此,現在我陷入了一個事實,無論我嘗試通過IEnumerable
進行迭代如何,我總會得到OutOfMemory異常。
我還嘗試通過在web.config
中將gcAllowVeryLargeObjects
設置為true來增加分配給對象的內存,但無濟於事:
<runtime>
<gcAllowVeryLargeObjects enabled="true"/>
</runtime>
其他嘗試:
谷歌搜索沒有帶來任何解決問題的方法,有什么建議/想法嗎?
最終,我不得不重寫代碼以實現外部庫以使用CsvHelper
庫將CSV序列化
using (StreamReader sr = new StreamReader(filePath))
{
var csvReader = new CsvReader(sr);
var records = csvReader.GetRecords<object>();
var result = string.Empty;
try
{
return JsonConvert.SerializeObject(new ServerData(records, _eventMessage));
}
catch (Exception ex)
{
_eventMessage.Level = EventMessage.EventLevel.Error;
}
return _serializer.Serialize(new ServerData(result, _eventMessage));
}
這似乎適用於大型數據集, OutOfMemory
異常不再出現
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.