簡體   English   中英

處理大文本(JSON)文件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM