2010-04-13 31 views
0

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

我的代码开始通过阅读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为100,流为200,我们将读取位置0-99,100-199,然后尝试读取200-299个错误。如果它返回0,我希望它,但它会引发错误。我在做什么来处理,没错,是一个try-catch:

catch (System.IndexOutOfRangeException) 
    numberOfBytesRead = 0; 

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

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

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

回答

1

您不必在黑暗中对斑点的大小:

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

......然后,你做你的阅读之前,你可以检查,看看index小于blobSize 。如果不是,你知道你已经封顶了,并且已经阅读了所有需要阅读的内容。

2

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

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

+0

虽然有,但我找到了答案,Henk将答案带入问题中,所以看起来好像没有答案。我的问题是关于获得偏移量0,偏移量100,然后在只有200的流中偏移200的语法。得到偏移量200是抛出IndexOutOfRangeException而不是返回0.也许这是MySqlDataReader中的错误? – dnord 2010-04-13 20:56:56

+0

我的答案是关于你的代码中的一个错误。 – 2010-04-13 21:10:54