IndexOutOfRangeException当流是缓冲区大小的倍数时

时间:2010-04-13 17:36:39

标签: c# streaming buffer sqldatareader binary-data

我没有很多关于流和缓冲区的经验,但是我不得不为一个项目做这件事,而且当我正在阅读的流是一个倍数时,我会被抛出一个异常被抛出我选择的缓冲区大小。让我告诉你:

我的代码首先从流中读取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);
}

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

但是如果bufferSize是100,并且流是200,我们将读取位置0-99,100-199,然后尝试读取200-299错误。如果它返回0,我会喜欢它,但它会抛出错误。我正在做的就是试一试:

catch (System.IndexOutOfRangeException)
    numberOfBytesRead = 0;

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

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

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

2 个答案:

答案 0 :(得分:2)

不确定这里是否有真正的问题。但是发布的代码根本就是错误的。一个流有义务返回请求的字节数。它可以减少回报,而且经常会回报。只有当它返回0时才知道你已到达流的末尾。

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

答案 1 :(得分:1)

你不必对这个blob的大小一无所知:

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

...然后,在您阅读之前,您只需检查index是否小于blobSize。如果不是,你知道你已经限制了它,并且阅读了所有要阅读的内容。