6

なぜこれほど多くの例がバイト配列をチャック内のストリームに読み取り、一度にすべてではないのか疑問に思っています...これは簡単な質問ですが、興味があります。

ハードウェアとバッファの充填はサイズに大きく依存する可能性があることを少し理解しています。バッファが必要な場所にフラッシュされるまで、バッファに再度書き込みたくないでしょう...ただし、.Netプラットフォーム(およびその他現代語)両方の例があります。では、いつ、どちらを使用するのか、それとも2番目は絶対にノーノーですか?

これが私が意味するもの(コード)です:

var buffer = new byte[4096];

while (true)
{
    var read = this.InputStream.Read(buffer, 0, buffer.Length);

    if (read == 0)
        break;

    OutputStream.Write(buffer, 0, read);
}

それよりも:

var buffer = new byte[InputStream.Length];

var read = this.InputStream.Read(buffer, 0, buffer.Length);

OutputStream.Write(buffer, 0, read);

どちらも合法だと思いますか?では、なぜwhileループの大騒ぎをすべて経験するのでしょうか(構造化することにした場合は何でも)。

私はできる限り多くを学びたいので、ここで悪魔の擁護者を演じています:)

4

4 に答える 4

20

最初のケースでは、必要なのは4kBのメモリだけです。2番目のケースでは、入力ストリームデータが使用するのと同じ量のメモリが必要です。入力ストリームが4GBの場合、4GBが必要です。

ファイルのコピー操作に4GBのRAMが必要だと思いますか?20GBのディスクイメージを準備する場合はどうなりますか?

パイプにもこのことがあります。Windowsではあまり使用しませんが、他のオペレーティングシステムでも同様のケースがよく見られます。2番目のケースは、すべてのデータが読み取られるのを待ってから、それらを出力に書き込みます。ただし、できるだけ早くデータを書き込むことをお勧めする場合があります。最初のケースでは、入力の最初の4kBが読み取られるとすぐに出力ストリームへの書き込みが開始されます。Webページの提供について考えてみてください。クライアントのWebブラウザが全体を待たずにヘッダーとコンテンツの最初の部分のレンダリングを開始するように、Webサーバーはできるだけ早くデータを送信することをお勧めします。

ただし、入力ストリームが4kBを超えないことがわかっている場合は、どちらの場合も同等です。

于 2012-11-28T14:24:33.487 に答える
6

場合によっては、InputStream.Lengthが、ネットトランスポートなどの一部のソースでは無効であるか、巨大なファイルからの読み取りなど、バッファが巨大である可能性があります。IMO。

于 2012-11-28T14:25:26.697 に答える
2

どれだけのデータReadが返されるかわかりません。非常に大きなファイルを読み取っている場合、これによりパフォーマンスに大きな問題が発生する可能性があります。

入力を制御でき、サイズが適切であることが確実な場合は、配列全体を一度に読み取ることができます。ただし、ユーザーが任意の入力を提供できる場合は特に注意してください。

于 2012-11-28T14:24:25.947 に答える
2

入力ストリームが数ギガバイトの長さである状況からユーザーを保護します。

于 2012-11-28T14:24:04.497 に答える