StreamReader仅读取文本文件首行,求助实现全行列加载至列表
解决StreamReader.ReadLine()仅读取首行就退出循环的问题
我之前也碰到过一模一样的坑!咱们一步步来排查和解决这个问题:
可能的原因 & 排查步骤
1. 文件换行符异常
有些文件可能用了非标准的换行符(比如只有\r而不是常见的\r\n/\n,甚至是特殊控制字符),虽然StreamReader.ReadLine()理论上支持多种换行序列,但极端情况下可能会误判为文件结束。
排查方法:用Notepad++打开目标文件,开启「视图→显示符号→显示所有字符」,查看第一行末尾的换行符是否正常,以及后续内容是否真的在新行上。
2. 编码不匹配
你指定了Encoding.UTF8,但如果文件实际编码不是UTF8(比如带BOM的UTF8、UTF16、GB2312等),读取时可能会把部分内容解析为EOF标记,导致提前退出循环。
解决尝试:让StreamReader自动检测编码,修改代码如下:
var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); // 第二个参数设为true,自动检测文件编码 using (var streamReader = new StreamReader(fileStream, true)) { string line; while ((line = streamReader.ReadLine()) != null) { destinationEmails.Add(line); } }
3. 文件流位置异常
如果在创建FileStream之前,这个文件的流被其他操作(比如之前的读取、写入)移动过位置,没有重置到开头,就会从中间开始读取,可能只读到第一行就到末尾了。
解决尝试:在创建StreamReader前,手动重置流的位置:
var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); fileStream.Seek(0, SeekOrigin.Begin); // 重置流到开头 using (var streamReader = new StreamReader(fileStream, Encoding.UTF8)) { string line; while ((line = streamReader.ReadLine()) != null) { destinationEmails.Add(line); } }
更简洁的替代方案
其实.NET提供了更省心的方法直接读取所有行,避开手动处理流的细节,试试这个:
// 一次性读取所有行,自动处理编码和流的问题 var allLines = File.ReadAllLines(filePath, Encoding.UTF8); destinationEmails.AddRange(allLines);
这个方法内部已经封装了所有流的操作,出错概率低很多,而且代码更简洁。
内容的提问来源于stack exchange,提问作者Albin
相关产品推荐
相关产品推荐

