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);
}

...そして、bufferSize 以外の読み取りに到達すると、ストリームの最後に達したことがわかり、先に進むことができます。

しかし、bufferSize が 100 で、ストリームが 200 の場合、0 から 99、100 から 199 の位置を読み取り、200 から 299 のエラーを読み取ろうとします。0が返ってくれればいいのですが、エラーになってしまいます。それを処理するために私がやっていることは、まあ、try-catchです:

catch (System.IndexOutOfRangeException)
    numberOfBytesRead = 0;

...これでループが終了し、正常に終了しますが、エラー処理でコード フローを制御したくないことは誰もが知っています。

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

これの詳細 (投稿用に少しクリーンアップしました) は、LAGEBLOB 列にヒットする MySqlDataReader です。バッファが返されたバイト数よりも大きい場合、または返されたバイト数がの倍数でないbufferSize場合は常に機能します。その場合、 . をスローしないためIndexOutOfRangeExceptionです。

4

2 に答える 2

2

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

これにより、ストリームは内部バッファーの使用を最適化し、オーバーラップ I/O スループットを向上させることができます。NetworkStream が良い例です。

于 2010-04-13T19:25:03.803 に答える
1

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

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

index...そして、読み取りを行う前に、が 未満であることを確認できますblobSize。そうでない場合は、上限を設定したことがわかり、読むべきものはすべて読んだことになります。

于 2010-04-13T17:46:44.083 に答える