简短回答
是的,你必须逐行循环。
详细说明
这里提供了最简单的方法,它取自 ReadAllLines
, File.cs > InternalReadAllLines
> ReadLine
, StreamReader.cs。
您可以看到参考版本正确处理所有的行结束符组合:\r、\n 和 \r\n。
ReadLine
方法在行终止符是 \r\n(DOS/Windows 通常会这样)时不会返回额外的空字符串。
ReadLine
也会丢弃最终分隔符之后的任何文本。
public static String[] ReadAllLines(this TextReader reader)
{
String line;
List<String> lines = new List<String>();
while ((line = reader.ReadLine()) != null)
{
lines.Add(line);
}
return lines.ToArray();
}
虽然有不使用 ReadAllLines
的原因,但这是提问者所要求的内容。
ReadAllLines
接受一个TextReader
,不仅限于 StreamReader
,同时支持 StringReader
。
顺便说一下,StreamReader
这个名称很糟糕,因为它并不读取流,而是为文件实现了 TextReader
。相比之下,Stream
是一个抽象类,提供字节序列的通用视图。换句话说,它可以是一个 FileStream——可能没有可适用的文本编码的二进制流。
为什么使用 ReadLine
文本文件是后缀分隔符,也就是说每行都以换行符结束。此外,在 Windows、Unix 和 Mac OS 上常用的换行符有 3 种组合方式。你的应用程序可能永远不会被移植到另一个操作系统,但可能需要从外部文件中读取来自外国操作系统的数据。
Split
不等同于 ReadLine
。 Split
最适合用于中缀分隔的字符串,例如逗号分隔的列表。对于后缀字符串来说,它不适用,因为分隔符可能是三种组合之一。 Split
将 \r 和 \n 视为两个分隔符并返回一个空字符串。它还会返回最后一个分隔符之后的任何文本。
某些其他答案中建议使用的 StringSplitOptions.RemoveEmptyEntries
选项会移除所有空行,包括原始输入中的空行。
因此,对于以下输入:
line1\r
\r
line3\r\n
ReadLine
返回 3 行,第二行为空。
Split
创建了 4 个字符串。(在最后一个 \n 后面还有一个额外的字符串。)然后它删除了第二个和第四个字符串。这不是 ReadAllLines
所做的。
reader.ReadToEnd().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
这个怎么样? - L.B