C# の System.IO.BufferedStream に代わるものはありますか?
-
23-08-2019 - |
質問
次の例外を受け取ります。
System.NotSupportedException : This stream does not support seek operations.
at System.Net.Sockets.NetworkStream.Seek(Int64 offset, SeekOrigin origin)
at System.IO.BufferedStream.FlushRead()
at System.IO.BufferedStream.WriteByte(Byte value)
次のリンクは、これが Microsoft の既知の問題であることを示しています。http://connect.microsoft.com/VisualStudio/フィードバック/ViewFeedback.aspx?FeedbackID=273186
このスタックトレースは 2 つのことを示しています。
- System.IO.BufferedStream は、不合理なポインター移動操作を実行します。BufferedStream は、基礎となるストリームをバッファリングする必要があり、それ以上はバッファリングしないでください。このようなシーク動作があるとバッファの品質が悪くなります。
- Seek をサポートしていないストリームでは安定して動作しません。
代替手段はありますか?C# では NetworkStream と一緒にバッファーが必要ですか、それとも既にバッファーされていますか。
編集:単純に、基礎となるソケット ストリームへの読み取り/書き込み呼び出しの数を減らしたいと考えています。
解決
ソリューション 2つの独立したものを使用することです BufferedStream
1 つは受信用、もう 1 つは送信用です。送信をフラッシュすることを忘れないでください BufferedStream
適当に。
2018 年現在でも、この質問に対して満足のいく答えを得るのは難しいようですが、人類のために、私の 2 セントをここに挙げておきます。
の NetworkStream
は OS側でバッファリングされます。ただし、.net 側でバッファする理由がないわけではありません。TCP は書き込み-読み取り (繰り返し) では正常に動作しますが、遅延 ACK などにより書き込み-書き込み-読み取りでは停止します。
私と同じように、21 世紀に持ち込むべき標準以下のプロトコル コードを大量に持っている場合は、バッファリングしたいと思うでしょう。
あるいは, 上記に従う場合は、読み取り/受信のみ、または書き込み/送信のみをバッファリングし、 NetworkStream
コードがどの程度壊れているかに応じて、相手側に直接送信されます。 ただ一貫性を保つ必要があります。
何 BufferedStream
ドキュメントでは、次のことを十分に明確にしていません。 ストリームがシーク可能な場合にのみ読み取りと書き込みを切り替えます. 。これは、読み取りと書き込みが同じバッファーにバッファリングされるためです。 BufferedStream
単純にうまく機能しない NetworkStream
.
Marc が指摘したように、この問題の原因は 2 つのストリームを 1 つの NetworkStream に統合することですが、これは .net の最大の設計上の決定の 1 つではありません。
他のヒント
NetworkStreamがすでにバッファリングされています。受信されたすべてのデータは、あなたがそれを読むために待っているバッファに保持されます。いずれかの非常に高速になります読み取るために、またはデータがネットワーク上の他のピアから受信されるため、BufferedStreamは、いずれの場合に役立つことはありません待ってブロックします呼び出します。
あなたがブロックを懸念しているなら、あなたは非ブロックモードに根本的なソケットを切り替えるを見ることができます。
BufferedStream
は、単に(結合IO /ハードウェアであってもよい)基本となるストリームに読み出し/書き込みコールの数を減らすように作用します。それが提供する機能を追求することはできません(実際、バッファリングと求めているが、多くの点でお互いに反している)。
なぜあなたは追求する必要がありますか? MemoryStream
またはFileStream
- - おそらく、最初のシーク可能な何かにストリームをコピーし、第2、シーク可能なストリームから、あなたの実際の作業を行います。
あなたは心の中で特定の目的を持っていますか?私はより詳細で、より適切な選択肢を提案することができるかもしれ...
具体的には:そのNetworkStream
が好奇心であることに注意 - 最もストリームと、同一の物理的ストリームに関連する読み取り/書き込み。しかし、NetworkStream
は、実際には2本の完全に独立したパイプを表します。読み取りおよび書き込みは完全に無関係です。同様に、あなたは にデータをスキップすることができます...すでに過去のZIP持っバイトに求めることはできないが、それは、より良い少数Read
のopdrationsを行うと、データを破棄することによって行われます。