读取大TXT文件,内存不足exception
我想读大TXT文件大小是500 MB,首先我使用
var file = new StreamReader(_filePath).ReadToEnd(); var lines = file.Split(new[] { '\n' });
但它抛出内存exception然后我试图逐行读取但是在读取大约150万行之后再次抛出内存exception
using (StreamReader r = new StreamReader(_filePath)) { while ((line = r.ReadLine()) != null) _lines.Add(line); }
或者我用过
foreach (var l in File.ReadLines(_filePath)) { _lines.Add(l); }
但我又收到了
mscorlib.dll中出现“System.OutOfMemoryException”类型的exception,但未在用户代码中处理
我的机器是function强大的机器,有8GB的内存,所以它不应该是我的机器问题。
ps:我试图在NotePadd ++中打开这个文件,我收到’文件太大而无法打开’exception。
只需使用File.ReadLines ,它返回IEnumerable
,并且不会一次性将所有行加载到内存中。
foreach (var line in File.ReadLines(_filePath)) { //Don't put "line" into a list or collection. //Just make your processing on it. }
exception的原因似乎是_lines集合的增长,但没有读取大文件。 您正在阅读行并adding to some collection _lines which will be taking memory and causing out of memory execption
。 您可以应用filter仅将所需的行放入_lines集合。
编辑:
将整个文件加载到内存中会导致对象增长,如果无法为对象分配足够的连续内存,.net将抛出OOMexception。
答案仍然是一样的,你需要流式传输文件,而不是读取整个内容。 这可能需要重新构建您的应用程序,但是使用IEnumerable<>
方法,您可以在应用程序的不同区域中堆叠业务流程并推迟处理。
具有8GB RAM的“强大”机器无法在内存中存储500GB文件,因为500大于8.(另外,由于操作系统将保留一些,因此你不能得到8,你可以在.Net中分配所有内存,32位有2GB限制,打开文件并存储该行将保存数据两次,有一个对象大小开销….)
您无法将整个内容加载到内存中进行处理,您必须通过处理流式传输文件。
你必须先计算线数。 它速度较慢,但最多可读取2,147,483,647行。
int intNoOfLines = 0; using (StreamReader oReader = new StreamReader(MyFilePath)) { while (oReader.ReadLine() != null) intNoOfLines++; } string[] strArrLines = new string[intNoOfLines]; int intIndex = 0; using (StreamReader oReader = new StreamReader(MyFilePath)) { string strLine; while ((strLine = oReader.ReadLine()) != null) { strArrLines[intIndex++] = strLine; } }