使用LINQ时,File.ReadAllLines是否延迟加载?

时间:2014-09-08 14:41:29

标签: c# linq lazy-loading file.readalllines

我想知道以下代码是否是延迟评估的,或者是否会以我处理ReadAllLines()可能的异常的方式崩溃。我确信Where子句是惰性评估的,但我不确定何时将它与ReadAllLines()一起使用。 可以解释如何以及为什么会受到赞赏。

File.ReadAllLines Exceptions

var fileLines = File.ReadAllLines(filePath).Where(line =>
{
    line = line.Trim();
    return line.Contains("hello");
});

string search;
try
{
    search = fileLines.Single();
}
catch (Exception exception)
{
    ...log the exception...
}

提前致谢

1 个答案:

答案 0 :(得分:9)

File.ReadAllLines不是延迟加载的,它会将所有内容加载到内存中。

string[]  allLines = File.ReadAllLines(filePath);

如果您想使用LINQ的延迟执行,您可以改为使用File.ReadLines

var fileLines = File.ReadLines(filePath)
    .Where(line =>
    {
        line = line.Trim();
        return line.Contains("hello");
    });

这也是documented

  

ReadLinesReadAllLines方法的不同之处如下:使用时   ReadLines您可以先开始枚举字符串集合   返回整个集合;当您使用ReadAllLines时,您必须   等待返回整个字符串数组,然后才能访问   数组。因此,当您使用非常大的文件时,   ReadLines可以更有效率。

但请注意,您必须小心使用ReadLines,因为您无法使用它两次。如果您尝试“执行”它,您将第二次获得ObjectDisposedException,因为基础流已经被处理掉了。 更新 This bug seems to be fixed.

这将导致异常,例如:

var lines = File.ReadLines(path);
string header = lines.First();
string secondLine = lines.Skip(1).First();

由于流仍处于打开状态,因此无法使用它来写入同一文件。

File.WriteAllLines(path, File.ReadLines(path)); // exception:  being used by another process.

在这些情况下,File.ReadAllLines更合适。