c#FileStream读取StreamReader EndOfStream存在问题

Ret*_*net 3 c# filestream streamreader

正如标题所说,我发现了一个问题.小故事第一:我们file.txt看起来像这样:

aaaabb
ccccddd
eeeefffffff
Run Code Online (Sandbox Code Playgroud)

有许多方法可以逐行阅读本文,其中一种方法是:

StreamReader sr = new StreamReader("file.txt");
while(!sr.EndOfStream)
{
    string s = sr.ReadLine();
}
sr.Close();
Run Code Online (Sandbox Code Playgroud)

作品.s得到每一行.现在我需要前4个字母作为字节,其余的作为字符串.在查看事物并尝试一点后,我发现最简单的方法是:

FileStream fs = new FileStream("file.txt", FileMode.Open);
StreamReader sr = new StreamReader(fs);
byte[] arr = new byte[4];
fs.Read(arr, 0, 4);
string s = sr.ReadLine();
sr.Close();
fs.Close();
Run Code Online (Sandbox Code Playgroud)

作品.arr包含前4个字母作为字节,其余部分保存在s.这只是一行.如果我们添加while:

FileStream fs = new FileStream("file.txt", FileMode.Open);
StreamReader sr = new StreamReader(fs);
while(!sr.EndOfStream)
{
    byte[] arr = new byte[4];
    fs.Read(arr, 0, 4);
    string s = sr.ReadLine();
} 
sr.Close();
fs.Close();
Run Code Online (Sandbox Code Playgroud)

现在有一个问题.现在arr没有得到任何东西,并s读取整行,包括前4个字母.更奇怪的是,如果我使用while(true)(并且我假设其他任何不是示例)而不是按预期工作,则4个字符作为字节,其余为字符串,这对于每一行都是相同的.

问题是我错过了什么?为什么会这样?我该如何解决这个问题?或者这可能是一个错误?

Kir*_*kin 7

这里的问题是简单的缓冲.当你附加StreamReader到它时FileStream,它最终消耗了一个文件块,从而推进了当前Position的FileStream.使用您的示例文件和默认缓冲区大小,一旦StreamReader附加自身,它基本上将整个文件消耗到缓冲区中,保留FileStream其EOF.然后,当您尝试FileStream直接通过fs引用读取4个字节时,没有什么可以消耗的.以下内容ReadLine适用于您的sr参考,因为它是从缓冲文件内容中读取的.

以下是对正在发生的事情的逐步细分:

  1. fs打开文件,位于Position0.
  2. sr包装fs和调用EndOfStream最终消耗(在这种情况下)27个字节到其内部缓冲区.此时,fs Position现在坐在EOF.
  3. 您尝试fs直接读取,但它在EOF处没有更多字节.
  4. sr.ReadLine 从步骤#2中构建的缓冲区读取,一切正常.

要修复特定的错误情况,可以将字节数组更改为char数组,然后使用sr.Read.即

char[] arr = new char[4];
sr.Read(arr, 0, 4);
Run Code Online (Sandbox Code Playgroud)