【问题标题】:How does StreamReader.ReadToEnd know it's at the end?StreamReader.ReadToEnd 怎么知道它在最后?
【发布时间】:2013-10-17 23:59:49
【问题描述】:

[这是一条红鲱鱼-很抱歉浪费人们的时间。虽然这些信息可能对其他人有用。]

我有一个自定义内存流,我已经将 StreamReader 包裹起来,以便通过ReadToEnd() 轻松读取其中的一些文本。问题是它永远不会结束。它不断地调用我的ReadByte() 函数,任何可以返回的值都可能是一个真实的值——所以与Read() 函数不同,我可以返回零来表示数据的结束,在这里我被卡住了。 ReadByte() 的规范说它在数据末尾返回 -1,但这不会导致 ReadToEnd() 停止。如果是这样,那就太没用了。

我在文档中只能找到 “ReadToEnd 假定流知道何时到达终点。” 但我看不出流如何发出这种情况的信号。

如果ReadByte() 在到达流的末尾时抛出异常,我分配输出的变量永远不会被设置,因为异常没有被 StreamReader 捕获。那么它从它下面的流中寻找什么条件来告诉它它已经到达流的末尾?


在所有 cmets 和更多挖掘之后,问题原来是我忘记的中间流,其中read() 正在调用子流的readbyte 并将返回的数据写入数组。感谢其中一个 cmets,当我发现我能够首先将 int 读入一个变量以检查它是否是 int -1 而不是 byte -1 来决定是继续写入数组还是退出时因为没有更多数据了。

所以我的问题的答案是信号是一个返回零的 Read(),如果你看到 ReadByte 在任何地方被调用,那么这就是开始怀疑的地方。

【问题讨论】:

  • 你知道 ReadByte 返回一个int,所以 -1 不同于任何真实字节?
  • Read 返回0 时,您就处于流的末尾。我不明白为什么 ReadByte 会被调用。
  • 是的。没有明确考虑到这一点,但我的函数声明为public override int ReadByte(),我有if (EndOfInput) return -1;。虽然我没有明确地将 -1 标记为 int,但上下文相关的弹出窗口将其标识为这样。尽管这种区别非常有用,但它并没有被利用。
  • @CraigGraham:查看 ILSpy 中的 StreamReader.ReadToEnd(至少是 .NET 4.0 版本),我看不出它会在哪里直接或间接调用 ReadByte。这是您使用的标准StreamReader 吗?
  • 如果没有重现问题的代码,我们只能对您的代码为什么不起作用以及为什么ReadByte 甚至被调用提供疯狂的猜测。 -1ReadByte 的正确信号,0Read 的正确信号。

标签: .net streamreader


【解决方案1】:

如果您要创建自定义 Stream 实现,则应覆盖 Read(byte[], int, int) 而不是 ReadByte()ReadByte() 的默认实现只是调用 Read(buffer, 0, 1) 作为实用方法。

StreamReader 将在底层流上调用 Read(byte[], int, int)。正确实现此方法以在到达流末尾时返回0 以解决问题。

【讨论】:

  • 其实docs说明ReadByte的默认实现效率很低,强烈建议不仅要覆盖Read,还要 ReadByte
  • 正确。 StreamReader AFAIK 不使用 ReadByte。为什么会这样?
  • 在实践中应该覆盖两者以提高性能。默认实现需要创建不必要的临时数组。但我不明白为什么 ReadByte 对这个问题很重要,因为 AFAIK StreamReader.ReadToEnd 没有调用它。
  • @usr 因为你不想搞砸一个字节[]而你只想要一个字节?
  • @Gusdor ReadToEnd 根据定义与byte[]s 相关,它返回一个。在 StreamReader 中使用临时的 byte[] 而不是 ReadByte 可以大大提高性能。在ReadToEnd 中使用ReadByte 会很愚蠢。
【解决方案2】:

如果您阅读代码,您会看到信号是 Stream.Read 返回 0。

【讨论】:

  • 问题已经说明了; OP 正在通过ReadByte 询问信号。
  • 没关系。当 Read 返回零时,ReadToEnd 停止。
猜你喜欢
  • 1970-01-01
  • 2020-02-03
  • 2011-11-21
  • 2014-01-25
  • 2010-09-08
  • 1970-01-01
  • 1970-01-01
  • 2010-10-16
  • 2017-03-14
相关资源
最近更新 更多