【问题标题】:IndexOutOfRangeException when a stream is a multiple of the buffer size当流是缓冲区大小的倍数时出现 IndexOutOfRangeException
【发布时间】:2010-04-14 22:20:40
【问题描述】:

我在流和缓冲区方面没有太多经验,但我必须为一个项目做这件事,当我正在读取的流是我选择的缓冲区大小。让我告诉你:

我的代码首先从流中读取 bufferSize(假设是 100 个)字节:

numberOfBytesRead = DataReader.GetBytes(0, index, output, 0, bufferSize);

然后,我循环一个while 循环:

while (numberOfBytesRead == bufferSize)
{
     BufferWriter.Write(output);
     BufferWriter.Flush();
     index += bufferSize;
     numberOfBytesRead = DataReader.GetBytes(0, index, output, 0, bufferSize);
}

...而且,一旦我们读取到 non-bufferSize,我们就知道我们已经到达流的末尾并且可以继续前进。

但如果 bufferSize 为 100,流为 200,我们将读取位置 0-99、100-199,然后尝试读取 200-299 错误。如果它返回 0,我会喜欢它,但它会引发错误。我正在做的事情是,好吧,一个尝试捕获:

catch (System.IndexOutOfRangeException)
    numberOfBytesRead = 0;

...结束循环,并成功完成事情,但我们都知道我不想通过错误处理来控制代码流。

当流长度未知时,是否有更好(更标准?)的方式来处理流读取?这似乎是一个相当合理的阅读流策略中的一个小皱纹,但我只是不知道我是不是弄错了。

这个的细节(我已经清理了一点)是一个 MySqlDataReader 命中一个 LARGEBLOB 列。只要缓冲区大于返回的字节数,或者返回的字节数不是bufferSize 的倍数,它就会起作用。因为在这种情况下,我们不会抛出IndexOutOfRangeException

【问题讨论】:

    标签: c# streaming buffer sqldatareader binary-data


    【解决方案1】:

    不确定这里是否存在真正的问题。但是发布的代码从根本上是错误的。流没有义务返回请求的字节数。它可以返回更少,而且经常这样做。只有当它返回 0 时,您才知道您已到达流的末尾。

    这允许流优化其内部缓冲区使用并提高重叠 I/O 吞吐量。 NetworkStream 就是一个很好的例子。

    【讨论】:

    • 有,但我找到了答案,Henk 将答案移到了问题中,所以看起来没有答案。我的问题是关于在只有 200 的流中获取偏移量 0、偏移量 100 和偏移量 200 的语法。获取偏移量 200 是抛出 IndexOutOfRangeException 而不是返回 0。也许这是 MySqlDataReader 中的错误?
    【解决方案2】:

    您不必对 blob 的大小一无所知:

    long blobSize = dr.GetBytes(0, 0, null, 0, 0);
    

    ...然后,在您阅读之前,您可以检查一下index 是否小于blobSize。如果不是,您知道您已经对其进行了限制,并且已经阅读了所有要阅读的内容。

    【讨论】:

      猜你喜欢
      • 2012-02-06
      • 1970-01-01
      • 2015-06-28
      • 2010-12-08
      • 2016-11-21
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      相关资源
      最近更新 更多