18

現在、NetworkStream.PeekC#にはメソッドがありません。NetworkStream.ReadByte返さbyteれたものが実際にから削除されないことを除いて、同じように機能するそのようなメソッドを実装するための最良の方法は何Streamですか?

4

4 に答える 4

9

実際にバイトを取得する必要がない場合は、DataAvailableプロパティを参照できます。

それ以外の場合は、でラップしてStreamReaderそのPeekメソッドを呼び出すことができます。

遅延の問題があるため、これらはどちらもネットワークストリームからの読み取りに特に信頼性がないことに注意してください。覗いた直後にデータが利用可能になる(読み取りバッファに存在する)可能性があります。

これで何をしようとしているのかわかりませんが、ReadonのメソッドNetworkStreamはブロッキング呼び出しであるため、チャンクで受信している場合でも、ステータスを確認する必要はありません。ストリームからの読み取り中にアプリケーションの応答性を維持しようとしている場合は、代わりにスレッドまたは非同期呼び出しを使用してデータを受信する必要があります。

編集:この投稿によると、StreamReader.PeekはバグがあるNetworkStreamか、少なくとも文書化されていない動作があるため、そのルートを選択する場合は注意してください。


更新-コメントへの応答

実際のストリーム自体の「ピーク」の概念は実際には不可能です。これは単なるストリームであり、バイトが受信されると、ストリーム上には存在しなくなります。一部のストリームはシークをサポートしているため、技術的にそのバイトを再読み取りできますが、NetworkStreamその1つではありません。

ピークは、ストリームをバッファに読み込んでいる場合にのみ適用されます。データがバッファに入ると、バッファの現在の位置にあるものをチェックするだけなので、覗き見が簡単になります。これが、aがこれを実行できる理由StreamReaderです。Stream通常、独自のPeekメソッドを持つクラスはありません。

さて、特にこの問題については、これが本当に正しい答えであるかどうか疑問に思います。ストリームを処理する方法を動的に選択するという考えは理解していますが、実際に生のストリームでこれを行う必要がありますか?ストリームを最初にバイト配列に読み込んだり、コピーしてMemoryStreamその時点から処理したりすることはできませんか?

私が目にする主な問題は、ネットワークストリームから読み取っているときに何か問題が発生した場合、データが失われることです。ただし、最初に一時的な場所に読み込むと、これをデバッグできます。データが何であったか、そしてデータを処理しようとしていたオブジェクトが途中で失敗した理由を知ることができます。

一般に、aで最初に実行したいのNetworkStreamは、ローカルバッファに読み込むことです。これを行わないと思う唯一の理由は、大量のデータを読み取っている場合です。それでも、ファイルシステムがメモリに収まらない場合は、ファイルシステムを中間バッファとして使用することを検討するかもしれません。

正確な要件はわかりませんが、これまでに学んだことから、私のアドバイスは次のようになりますNetworkStream。やむを得ない理由がない限り、データを直接処理しようとしないでください。最初にデータをメモリまたはディスクに読み込んでから、コピーを処理することを検討してください。

于 2010-02-04T01:26:27.977 に答える
5

Socketオブジェクトにアクセスできる場合は、 Receive メソッドを試して を渡すことができますSocketFlags.Peek。これは、BSD ソケットまたは Winsock で呼び出しにMSG_PEEK渡すことができるフラグに似ています。recv

于 2011-07-01T18:45:37.567 に答える