为什么Peek和Read在C#中使用整数来警告您文件的末尾,而不是使用异常来检查streamreader的末尾

本文关键字:streamreader 检查 异常 警告 Read Peek 为什么 整数 文件 | 更新日期: 2023-09-27 18:27:18

I并编写一个非常简单的C#类来读取UTF8文件的所有字符。

对于主循环,检测文件结尾的条件是:

while (!fin.EndOfStream) 
{
    int c = fin.Read();
    <some text processing>
}

但我至少知道另外两种方法:

while (fin.Peek() >= 0)
{
    int c = fin.Read();
    <some text processing>
}

和:

int c = 0;
while ((c = fin.Read()) >= 0) 
{
   <some text processing>
}

对我来说,第一种形式是最好的:更短、更清晰,条件很容易理解,当你到达文件末尾时,你不必知道Read()或Peek()返回-1。

除了第二种和第三种形式之外,不要遵循信息隐藏原则(维基百科引用):信息隐藏原理。

我的问题是:

为什么有这么多方法可以检查文件末尾?

为什么要花费时间和资源来设计、编码、测试和维护这么多检查文件末尾的方法?

编辑:

Read和Peek警告你文件的末尾,你可以用它们来做EndOfStream被禁止做的工作。我的意思是:Read和Peck正在做他们自己的工作,以及EndOfStream的工作,所以Read和Peak正在做更多的工作,这是他们的名字所暗示的。无论何时到达文件末尾,都可以使用异常,而不是整数。

为什么Peek和Read在C#中使用整数来警告您文件的末尾,而不是使用异常来检查streamreader的末尾

你的问题的前提是错误的。

所有这些函数都有不同的语义和不同的用途。仅仅因为它们在一个上下文中是可互换的,并不意味着你可以在每个上下文中自由地进行。只有一种方法是专门为检查流的末尾而设计的——fin.EndOfStream

仅仅因为人们用棒球棍打别人,并不意味着棒球棍是多余和无用的,因为还有其他(甚至更好的)方法。它们在不同的环境中都有其用途。

实际上,有人可能会争辩(至少在我看来),fin.EndOfStream可能对(fin.Peek() >= 0)是多余的,或者语言设计者本可以这样做,但他们决定允许程序在语义上是干净的。检查流的末尾感觉比偷看下一个预期错误的字符更自然。

你所谈论的每种方法和属性的存在都是合理的。

Peek等于Read而不影响流的状态,因此我不会将其视为"备选方案"。还有一些其他类提供PeekRead选项。

还有其他类使用Read来读取和通知流的结束,例如,XmlReader返回bool而不是数字。

我同意你的观点,使用数字作为是否达到终点的指示是奇数。顺便说一句,流末尾的Read的返回值是0,而不是-1,当数据不可用时,记录流以阻止数据,直到数据可用为止(因为如果返回0,则意味着流的末尾)。他们本可以选择bool TryRead(..., out int bytes)

我不知道关于Stream的决定是如何做出的,但如果它满足了你的问题,我们可以假装他们的想法和你完全一样,并为不喜欢其他方法的人创建了EndOfStream属性。这方面的一种证据是Stream的实现者不必实现EndOfStream,因为它只是表示最后一个Read操作的状态。