我注意到在 ReadLine()StreamReader 上使用 StringReader 时,如果文件或字符串以换行符结尾,则该字符序列将完全丢失。考虑以下示例:

static void Main(string[] args)
{
    string data = "First Line\r\nSecond Line\r\n\r\n\r\n";
    List<string> lineData = new List<string>();
    string[] splitData = data.Split(
        new string[] { "\r\n" },
        StringSplitOptions.None);

    using (StringReader sr = new StringReader(data))
    {
        string line;
        while ((line = sr.ReadLine()) != null)
            lineData.Add(line);
    }

    Console.WriteLine("Raw Line Count: " + splitData.Length);
    Console.WriteLine("StringReader Line Count: " + lineData.Count);
    Console.WriteLine("Split Data: ");
    foreach (string s in splitData)
        Console.WriteLine(string.IsNullOrEmpty(s) ? "[blank line]" : s);
    Console.WriteLine("StringReader Data: ");
    foreach (string s in lineData)
        Console.WriteLine(string.IsNullOrEmpty(s) ? "[blank line]" : s);
    Console.ReadKey();
}

输出是这样的:
Raw Line Count: 5
StringReader Line Count: 4
Split Data:
First Line
Second Line
[blank line]
[blank line]
[blank line]
StringReader Data:
First Line
Second Line
[blank line]
[blank line]

为什么 StringReader/StreamReader 会这样?我可以想到几种解决方法,但是因为读者的行为出乎意料,所以不得不重新编写我的代码似乎很愚蠢。某些 .NET 库中是否有一些设置会影响流处理最终换行符的方式?

编辑

这是另一个示例:先对 "First Line\r\nSecond Line" 再对 "First Line\r\nSecond Line\r\n" 运行示例时比较结果。结果完全相同(就示例的 StringReader 部分而言)。为什么 StringReader 会在第二个示例中返回 null 而不是空字符串?我知道从 ReadLine() 返回的字符串不包括换行符,但为什么最后一行会被解释为 null 而不是 ""

最佳答案

输出的差异不是因为 StringReader 的奇怪行为。请注意,您的输入仅包含四行,并且正在读取四行(仅没有结束换行符,如 documentation 所指定)。 Split 方法引入了一个额外的行——因为如果您想保留空条目,则会在最后一个标记之后创建一个不存在的条目。
StringReader 的输出:

"First Line\r\nSecond Line\r\n\r\n\r\n";
 ^1st          ^2nd           ^3rd^4th   (line)
Split 的输出:
"First Line\r\nSecond Line\r\n\r\n\r\n";
 ^1st          ^2nd           ^3rd^4th^5th (token)

考虑这个输入:
"First line\r\n"

它是几行?一,这就是输出:
Split Data:
First Line
[blank line]
StringReader Data:
First Line

所以似乎 Split 是这里的“问题”(如果有的话)。

Douglas 在下面的评论中描述了真正的问题,它是像 "ABC\r\nXYZ""ABC\r\nXYZ\r\n" 这样的输入是无法区分的。但是,在 ReadLine 接口(interface)的典型用例中,您并不关心这一点。如果您想关心,则需要使用级别稍低的接口(interface)(例如 Read )。

关于c# - StringReader 省略尾随换行符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19365404/

10-13 02:43