为什么 StreamReader.EndOfStream 属性更改 BaseStream.Position 值

2023-11-29

我编写了这个小程序,它从 Random.txt 中读取每 5 个字符 在 random.txt 中,我有一行文本:ABCDEFGHIJKLMNOPRST。我得到了预期的结果:

  • A的位置为0
  • F的位置是5
  • K的位置是10
  • P的位置是15

这是代码:

static void Main(string[] args)
{
    StreamReader fp;
    int n;
    fp = new StreamReader("d:\\RANDOM.txt");
    long previousBSposition = fp.BaseStream.Position;
    //In this point BaseStream.Position is 0, as expected
    n = 0;

    while (!fp.EndOfStream)
    {
        //After !fp.EndOfStream were executed, BaseStream.Position is changed to 19,
        //so I have to reset it to a previous position :S
        fp.BaseStream.Seek(previousBSposition, SeekOrigin.Begin);
        Console.WriteLine("Position of " + Convert.ToChar(fp.Read()) + " is " + fp.BaseStream.Position);
        n = n + 5;
        fp.DiscardBufferedData();
        fp.BaseStream.Seek(n, SeekOrigin.Begin);
        previousBSposition = fp.BaseStream.Position;
    }
}

我的问题是,为什么行后while (!fp.EndOfStream) BaseStream.Position更改为 19,例如结束一个BaseStream。我预计,显然是错误的BaseStream.Position当我打电话时会保持不变EndOfStream check?

Thanks.


确定是否存在的唯一确定方法Stream最后就是实际读取其中的内容并检查返回值是否为0。(StreamReader有另一种方法 - 检查其内部缓冲区,但你正确地不让它通过调用来做到这一点DiscardBufferedData.)

So, EndOfStream必须从基本流中读取至少一个字节。由于逐字节读取效率低下,因此会读取更多内容。这就是为什么调用EndOfStream将位置更改为末尾(对于较大的文件来说,这不是文件末尾)。

看来你实际上并不需要使用StreamReader,所以你应该使用Stream(或者具体来说FileStream) 直接地:

using (Stream fp = new FileStream(@"d:\RANDOM.txt", FileMode.Open))
{
    int n = 0;

    while (true)
    {
        int read = fp.ReadByte();
        if (read == -1)
            break;

        char c = (char)read;
        Console.WriteLine("Position of {0}  is {1}.", c, fp.Position);
        n += 5;
        fp.Position = n;
    }
}

(我不确定在这种情况下设置超出文件末尾的位置会做什么,您可能需要为此添加检查。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 StreamReader.EndOfStream 属性更改 BaseStream.Position 值 的相关文章

随机推荐