我没有很多关于流和缓冲区的经验,但是我不得不为一个项目做这件事,而且当我正在阅读的流是一个倍数时,我会被抛出一个异常被抛出我选择的缓冲区大小。让我告诉你:
我的代码首先从流中读取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
。
答案 0 :(得分:2)
不确定这里是否有真正的问题。但是发布的代码根本就是错误的。一个流不有义务返回请求的字节数。它可以减少回报,而且经常会回报。只有当它返回0时才知道你已到达流的末尾。
这允许流优化其内部缓冲区使用并提高重叠的I / O吞吐量。 NetworkStream就是一个很好的例子。
答案 1 :(得分:1)
你不必对这个blob的大小一无所知:
long blobSize = dr.GetBytes(0, 0, null, 0, 0);
...然后,在您阅读之前,您只需检查index
是否小于blobSize
。如果不是,你知道你已经限制了它,并且阅读了所有要阅读的内容。