File.ReadLines 抛出 OutOfMemoryException
File.ReadLines throws OutOfMemoryException
我有一个奇怪的问题,我似乎找不到解决方案。
我正在尝试按 800 万行的块读取大文件(从 500Mb 到 2Gb)。
为此,我创建了以下内容:
public static List<string> read_file(string path, Int32 start, Int32 end, Boolean is_big_file)
{
try
{
List<string> lines = new List<string>();
if (is_big_file)
lines = File.ReadLines(path).Skip(start).Take(end - start).ToList();
else
lines = File.ReadAllLines(path).ToList();
return lines;
}
catch { return null; }
}
如果文件少于 8M 行,则使用 ReadAllLines 并且一切正常。
如果文件多于此,它将使用 ReadLines.Skip.Take.
第一个块有效,我收到了前 8 M 行。
开始 = 0。结束 = 8,000,000。
第二个块不起作用。
开始 = 8,000,000。 end = 16,000,000 或文件的最后一行(取决于行数)。
出于某种原因,当我要读取的行数少于 8M (end = 12,500,000) 时,我得到 OutOfMemoryException。
你知道为什么会这样吗? Skip 是否也缓存原始行?
有没有更优雅的解决方案?
谢谢!
实际上,使用这个:
File.ReadLines(path)
您正在阅读 ALL 行。您最好对要读取的字节使用 FileStream
和 Seek
。像这样:
using (FileStream fs = new FileStream(path, FileMode.Open))
{
fs.Seek(start, SeekOrigin.Begin);
TextReader tr = new StreamReader(fs);
string line = tr.ReadLine();
}
我有一个奇怪的问题,我似乎找不到解决方案。 我正在尝试按 800 万行的块读取大文件(从 500Mb 到 2Gb)。
为此,我创建了以下内容:
public static List<string> read_file(string path, Int32 start, Int32 end, Boolean is_big_file)
{
try
{
List<string> lines = new List<string>();
if (is_big_file)
lines = File.ReadLines(path).Skip(start).Take(end - start).ToList();
else
lines = File.ReadAllLines(path).ToList();
return lines;
}
catch { return null; }
}
如果文件少于 8M 行,则使用 ReadAllLines 并且一切正常。 如果文件多于此,它将使用 ReadLines.Skip.Take.
第一个块有效,我收到了前 8 M 行。 开始 = 0。结束 = 8,000,000。
第二个块不起作用。 开始 = 8,000,000。 end = 16,000,000 或文件的最后一行(取决于行数)。 出于某种原因,当我要读取的行数少于 8M (end = 12,500,000) 时,我得到 OutOfMemoryException。
你知道为什么会这样吗? Skip 是否也缓存原始行? 有没有更优雅的解决方案?
谢谢!
实际上,使用这个:
File.ReadLines(path)
您正在阅读 ALL 行。您最好对要读取的字节使用 FileStream
和 Seek
。像这样:
using (FileStream fs = new FileStream(path, FileMode.Open))
{
fs.Seek(start, SeekOrigin.Begin);
TextReader tr = new StreamReader(fs);
string line = tr.ReadLine();
}