为什么 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();
您正在丢失行尾字符。
我尝试使用两个代码块从 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();
您正在丢失行尾字符。