我有一个很大的JSON对象,我需要传递给Web浏览器中显示的视图。由于我不能让一个带有Action的Controller返回这个JSON对象,我想在Razor视图中添加JSON对象。
@Html.Hidden("fileContent", fileContent);
<textarea style="display:none">
@fileContent
</textarea>
上述所有内容都不如我所期望的那样,并且给了我,
类型的异常&#39; System.OutOfMemoryException&#39;被扔了。
描述:执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。
异常详细信息:System.OutOfMemoryException:类型的异常&#39; System.OutOfMemoryException&#39;被扔了。
是的,我同意以另一种方式(may be as Mediator suggest重组流程或者有一个返回JSON对象的操作更好。)
感谢您的时间。任何帮助都将受到高度赞赏。
修改
控制器的
var file = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/content/data.csv"));
ViewData.Add("file", file);
return View();
堆栈跟踪
[OutOfMemoryException:类型的异常&#39; System.OutOfMemoryException&#39; 被抛出。] System.Text.StringBuilder.ExpandByABlock(Int32 minBlockCharCount)+163 System.Text.StringBuilder.Append(Char * value,Int32 valueCount)+82
System.Text.StringBuilder.AppendHelper(String value)+31
System.Text.StringBuilder.Append(String value)+186
System.IO.StringWriter.Write(String value)+30
System.Web.WebPages.WebPageBase.Write(Object value)+87
答案 0 :(得分:-1)
根据您的CSV文件大小,最好使用ReadLines
而不是ReadAllText
,如下所示:
var sb = new StringBuilder();
sb.Capacity = 16; // default, adjust it to less number as you wish
foreach (String line in System.IO.File.ReadLines(HttpContext.Server.MapPath("~/content/data.csv")))
{
sb.Append(line);
}
ViewData.Add("file", sb.ToString());
ReadLines
返回IEnumerable<String>
逐行读取文件(一次一行),因此它适用于某些文件,这些文件在存储为单个大字符串时可能会占用大量内存空间。 / p>
但是,如果文件内容非常大,请考虑使用StreamReader
而不是StringBuilder
,这需要连续的数组大小并取决于heap fragmentation:
using (var sr = new System.IO.StreamReader(HttpContext.Server.MapPath("~/content/data.csv")))
{
String line;
while ((line = sr.ReadLine()) != null)
{
// combine source strings here
}
}
请注意,每个字符需要2个字节,字符串是字符数组,因此应该有连续的数组,这些数组会在内存中生成对象时影响性能和大小。因此,在处理需要立即清理的大量对象后,使用GC.Collect()
方法优化垃圾收集器功能可能会有所帮助。
相关参考资料:
interesting OutOfMemoryException with StringBuilder
MSDN: System.Text.StringBuilder
Eric Lippert: Out Of Memory” Does Not Refer to Physical Memory