c# - 需要帮助理解 Microsoft 对 File.ReadLines 和 File.ReadAllLines 的解释

标签 c# readlines file.readalllines

根据微软对ReadLinesReadAllLines方法的解释,当你使用ReadLines时,你可以开始枚举字符串集合在返回整个集合之前。使用 ReadAllLines 时,必须等待返回整个字符串数组,然后才能访问该数组。因此,当您处理非常大的文件时,ReadLines 会更有效率。

当他们说:

1 - “当您使用 ReadLines 时,您可以在返回整个集合之前开始枚举字符串集合。” 如果写了下面这行代码,那是不是意味着ReadLines方法执行结束,整个集合返回并存储在变量filedata中?

IEnumerable<String> filedata = File.ReadLines(fileWithPath)

2 - “当您使用 ReadAllLines 时,必须等待整个字符串数组返回后才能访问该数组”。这是否意味着,在下面的代码片段中,如果读取了一个大文件,那么如果在读取文件后立即使用,数组变量 hugeFileData 将不会包含所有数据?

string[] hugeFileData = File.ReadAllLines(path)
string i = hugeFileData[hugeFileData.length-1];

3 - “当您处理非常大的文件时,ReadLines 会更有效率”。如果是这样,下面的代码在读取大文件时是否有效?我相信下面代码的第 2 行和第 3 行会读取文件两次,如果我错了请纠正我。

string fileWithPath = "some large sized file path";
string lastLine = File.ReadLines(fileWithPath).Last();
int totalLines = File.ReadLines(fileWithPath).Count();

在上面的代码片段中对同一个文件调用 ReadLines 两次的原因是,当我尝试下面的代码时,我在第 3 行得到了一个异常“无法从关闭的 TextReader 中读取”在下面的代码片段中。

IEnumerable<String> filedata = File.ReadLines(fileWithPath);
string lastLine = filedata.Last();
int totalLines = filedata.Count();

最佳答案

ReadLinesReadAllLines 之间的区别很容易用代码说明。

如果你这样写:

foreach (var line in File.ReadLines(filename))
{
    Console.WriteLine(line);
}

发生的事情与此类似:

using (var reader = new StreamReader(filename))
{
    while (!reader.EndOfStream)
    {
        var line = reader.ReadLine();
        Console.WriteLine(line);
    }
}

实际生成的代码稍微复杂一些(ReadLines 返回一个枚举器,其 MoveNext 方法读取并返回每一行),但从外部看行为是相似的。

该行为的关键是 deferred execution ,为了充分利用 LINQ,您应该很好地理解它。所以你的第一个问题的答案是“否”。对 ReadLines 的所有调用都是打开文件并返回一个枚举器。除非您要求,否则它不会读取第一行。

这里注意,代码甚至可以在读取第二行之前输出第一行。此外,您一次只能为一行使用内存。

ReadAllLines 有很多不同的行为。当你写:

foreach (var line in File.ReadAllLines(filename))
{
    Console.WriteLine(line);
}

实际发生的情况更像是这样:

List<string> lines = new List<string>();
using (var reader = new StreamReader(filename))
{
    while (!reader.EndOfStream)
    {
        var line = reader.ReadLine();
        lines.Add(line);
    }
}
foreach (var line in lines)
{
    Console.WriteLine(line);
}

这里,程序必须先将整个文件加载到内存中,然后才能输出第一行。

你使用哪一个取决于你想做什么。如果您只需要逐行访问文件,那么 ReadLines 通常是更好的选择——尤其是对于大文件。但是如果您想随机访问行或者如果您要多次读取文件,那么 ReadAllLines 可能会更好。但是,请记住 ReadAllLines 要求您有足够的内存来容纳整个文件。

在你的第三个问题中,你展示了这段代码,它在最后一行产生了一个异常:

IEnumerable<String> filedata = File.ReadLines(fileWithPath);
string lastLine = filedata.Last();
int totalLines = filedata.Count();

这里发生的事情是第一行返回了一个枚举器。第二行代码枚举了整个序列(即读取到文件末尾),以便它可以找到最后一行。枚举器看到它在文件末尾并关闭了关联的阅读器。最后一行代码再次尝试枚举文件,但文件已经关闭。 ReadLines 返回的枚举器中没有“重置到文件开头”的功能。

关于c# - 需要帮助理解 Microsoft 对 File.ReadLines 和 File.ReadAllLines 的解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24916717/

相关文章:

c# - 将 PropertyChangedCallback 标记为异步是否安全?

c++ - 如何让程序读取一行? C++

Python:读取 .txt 文件而不将其内容放入字符串中

c# - File.ReadAllLines() 和 File.ReadAllText() 有什么区别?

python - file.read 返回空列表

java - 使用java split从文件中解析日期

c# - 如何在给定 XmlWriter 的情况下创建 XDocument?

c# - 代码中的访问控制属性

python - 从文本文件中读取特定行,然后检查它是否等于字符串变量?

c# - 使用 linq 获取逗号分隔的实体集合列表