Is File.ReadAllLines lazy loaded when using with LINQ Where?
Asked Answered
J

1

5

I would like to know if the following code is lazy evaluated or will crash in the way I handle possible exception of ReadAllLines(). I know for sure that Where clause is lazy evaluated but I'm not sure when I use it with ReadAllLines(). A possible explanation of how and why would be appreciated.

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...
}

Thanks in advance.

Jannjanna answered 8/9, 2014 at 14:41 Comment(1)
T[] is never lazy, since it requires a consecutive block of memory.Dike
A
10

File.ReadAllLines is not lazy loaded, it loads all into memory.

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

If you want to use LINQ's deferred execution you can use File.ReadLines instead:

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

This is also documented:

The ReadLines and ReadAllLines methods differ as follows: When you use ReadLines, you can start enumerating the collection of strings before the whole collection is returned; when you use ReadAllLines, you must wait for the whole array of strings be returned before you can access the array. Therefore, when you are working with very large files, ReadLines can be more efficient.

But note that you have to be careful with ReadLines since you cannot use it twice. If you try to "execute" it a second time you'll get an ObjectDisposedException since the underlying stream is already disposed. Update This bug seems to be fixed.

This will cause an exception for example:

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

You cannot use it either to write to the same file since the stream is still open.

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

In these cases File.ReadAllLines is more appropriate.

Artima answered 8/9, 2014 at 14:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.