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

本文关键字:字符 FileStream 为什么 | 更新日期: 2023-09-27 18:14:57

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

我注意到第一块代码正确地读取了我所有的回车和换行,而另一块忽略了它们。我不确定这里到底发生了什么。我以两种不同的方式打开流,但这并不重要,对吧?好吧,在任何情况下,这是第一块代码(正确读取我的空白字符):

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

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

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.");
}

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

生成的新文件
foreach(var l in content)
{
    sw.Write(l);
}

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

正如@DaveKidder在这个线程中指出的那样,StreamReader的规范。ReadLine明确表示生成的行不包括行尾。

当你这样做

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

您正在丢失行尾字符。