加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 需要帮助理解Microsoft对File.ReadLines和File.ReadAllLin

发布时间:2020-12-15 23:43:58 所属栏目:百科 来源:网络整理
导读:根据Microsoft对ReadLines和ReadAllLines方法的解释,当您使用ReadLines时,您可以在返回整个集合之前开始枚举字符串集合.使用ReadAllLines时,必须等待返回整个字符串数组才能访问该数组.因此,当您使用非常大的文件时,ReadLines可以更高效. 当他们说: 1 – “
根据Microsoft对ReadLines和ReadAllLines方法的解释,当您使用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可以更高效”.如果是这样,那么在读取大文件时,以下代码是否有效?我相信第二行和第三行下面的代码会读取文件两次,如果我错了,请纠正我.

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();

解决方法

ReadLines和ReadAllLines之间的区别很容易通过代码来说明.

如果你这样写:

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返回的枚举器中没有“重置到文件的开头”功能.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读