0


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);
}
  1. そして、一度bufferSize以外の読み取りを取得すると、最後に到達したことがわかります ストリームのと移動することができます。

ただし、bufferSizeが100で、ストリームが200の場合、0〜99、100〜199の位置を読み取り、200〜299のエラーを読み取ろうとします。 0が返されたらいいのですが、エラーがスローされます。 それを処理するために私がやっていることは、まあ、トライキャッチです:

catch (System.IndexOutOfRangeException)
    numberOfBytesRead = 0;

…​which ends the loop, and successfully finishes the thing, but we all エラー処理でコードフローを制御したくないことを知っています。

ストリームの長さが不明な場合にストリームの読み取りを処理するより良い(より標準的な)方法はありますか? これは、ストリームを読み取るためのかなり合理的な戦略の小さなしわのように見えますが、間違っているのか、それとも何を知っているのかわかりません。

これの詳細(投稿のために少し整理しました)は、LARGEBLOB列にヒットするMySqlDataReaderです。 バッファーが返されたバイト数よりも大きい場合、または返されたバイト数が「bufferSize」の倍数ではない場合に機能します。 その場合、 `IndexOutOfRangeException`をスローしないためです。

2 Answer


2


ここに本当の質問があるかどうかわかりません。 しかし、投稿されたコードは根本的に間違っています。 ストリームには、要求されたバイト数を返す義務がありません。 返される可能性は少なく、しばしば返されます。 0が返された場合にのみ、ストリームの終わりに到達したという事実がわかります。

これにより、ストリームは内部バッファーの使用を最適化し、重複したI / Oスループットを改善できます。 NetworkStreamは良い例です。


1


ブロブのサイズについて暗闇にいる必要はありません。

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

…​and then, before you do your read, you can just check to see that index`は blobSize`よりも小さいです。 そうでない場合、あなたはあなたがそれをキャップしたことを知っており、読むためにそこにあるすべてを読んだ。