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

我写了这个小程序,它从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;
    }
}

我的问题是,为什么在行之后(!fp.EndOfStream)将BaseStream.Position更改为19,例如BaseStream的结尾.当我调用EndOfStream检查时,我预计,显然是错误的,BaseStream.Position将保持不变?

谢谢.

解决方法

只有某种方法来确定Stream是否在其末端才能实际从中读取内容并检查返回值是否为0.(StreamReader有另一种方法 – 检查其内部缓冲区,但你正确地不让它做通过调用discardBufferedData.)

因此,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;
    }
}

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

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...