为什么 FileStream 有时会忽略不可见字符?

Why does FileStream sometimes ignore invisible characters?

我尝试使用两个代码块从 C# 中的文件流中读取数据。我在这里的总体目标是尝试将每一行文本读入一个字符串列表,但它们都被读入一个字符串(当以读+写访问 together 打开时)。 ..

我注意到第一段代码正确读取了我所有的回车 return 和换行符,而另一段代码忽略了它们。我不确定这里到底发生了什么。我以两种不同的方式打开流,但这应该无关紧要吧?好吧,无论如何这是第一段代码(正确读入我的白色 space 字符):

StreamReader sr = null;
StreamWriter sw = null;
FileStream fs = null;
List<string> content = new List<string>();
List<string> actual = new List<string>();
string line = string.Empty;

// first, open up the file for reading
fs = File.OpenRead(path);
sr = new StreamReader(fs);

// read-in the entire file line-by-line
while(!string.IsNullOrEmpty((line = sr.ReadLine())))
{
    content.Add(line);
}
sr.Close();

现在,这是忽略所有白色-space字符(即换行符、回车-return)并在一行中读取整个文件的代码块。

StreamReader sr = null;
StreamWriter sw = null;
FileStream fs = null;
List<string> content = new List<string>();
List<string> actual = new List<string>();
string line = string.Empty;

// first, open up the file for reading/writing
fs = File.Open(path, FileMode.Open);
sr = new StreamReader(fs);

// read-in the entire file line-by-line
while(!string.IsNullOrEmpty((line = sr.ReadLine())))
{
    content.Add(line);
}
sr.Close();

为什么Open导致所有数据读为单行,而OpenRead正常工作(读数据为多行)?

更新 1

我被要求提供重现问题的文件的文本。所以它在下面(确保 CR+LF 在每行的末尾!!我不确定它是否会被粘贴在这里!

;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;$$$$$$$$$                                                                $$$$$$$
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;
;
;

更新 2

重现问题的确切代码块(使用上面的文本作为文件)。在这种情况下,我实际上看到了问题而没有尝试 Open 并且只使用 OpenRead.

StreamReader sr = null;
StreamWriter sw = null;
FileStream fs = null;
List<string> content = new List<string>();
List<string> actual = new List<string>();
string line = string.Empty;

try
{
    // first, open up the file for reading/writing
    fs = File.OpenRead(path);
    sr = new StreamReader(fs);

    // read-in the entire file line-by-line
    while(!string.IsNullOrEmpty((line = sr.ReadLine())))
    {
        content.Add(line);
    }
    sr.Close();

    // now, erase the contents of the file
    File.WriteAllText(path, string.Empty);

    // make sure that the contents of the file have been erased
    fs = File.OpenRead(path);
    sr = new StreamReader(fs);
    if (!string.IsNullOrEmpty(line = sr.ReadLine()))
    {
        Trace.WriteLine("Failed: Could not erase the contents of the file.");
        Assert.Fail();
    }
    else
    {
        Trace.WriteLine("Passed: Successfully erased the contents of the file.");
    }

    // now, attempt to over-write the contents of the file
    fs.Close();
    fs = File.OpenWrite(path);
    sw = new StreamWriter(fs);
    foreach(var l in content)
    {
        sw.Write(l);
    }

    // read back the over-written contents of the file
    fs.Close();
    fs = File.OpenRead(path);
    sr = new StreamReader(fs);
    while (!string.IsNullOrEmpty((line = sr.ReadLine())))
    {
        actual.Add(line);
    }

    // make sure the contents of the file are correct
    if(content.SequenceEqual(actual))
    {
        Trace.WriteLine("Passed: The contents that were over-written are correct!");
    }
    else
    {
        Trace.WriteLine("Failed: The contents that were over-written are not correct!");
    }
}
finally
{
    // close out all the streams
    fs.Close();

    // finish-up with a message
    Trace.WriteLine("Finished running the overwrite-file test.");
}

您的新文件由

生成
foreach(var l in content)
{
    sw.Write(l);
}

不包含行尾字符,因为 content 中不包含行尾字符。

正如@DaveKidder 在this thread over here, the spec for StreamReader.ReadLine 中指出的那样,特别指出生成的行不包括行尾。

当你这样做时

while(!string.IsNullOrEmpty((line = sr.ReadLine())))
{
    content.Add(line);
}
sr.Close();

您正在丢失行尾字符。