0

我在流和缓冲区方面没有很多经验,但是我必须为一个项目做这件事,当我正在读取的流是缓冲区大小的倍数时,我被抛出异常我已经选择了。我来给你展示:

我的代码首先从流中读取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,我会喜欢它,但它会引发错误。我正在做的事情是,好吧,一个try-catch:

catch (System.IndexOutOfRangeException)
    numberOfBytesRead = 0;

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

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

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

4

2 回答 2

2

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

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

于 2010-04-13T19:25:03.803 回答
1

You don't have to be in the dark about the blob's size:

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

...and then, before you do your read, you can just check to see that index is less than blobSize. If it isn't, you know you've capped it, and have read everything there is to read.

于 2010-04-13T17:46:44.083 回答