2 Stimmen

Gibt es eine Alternative zu System.IO.BufferedStream in C#?

Ich erhalte die folgende Ausnahme:

System.NotSupportedException : Dieser Stream unterstützt keine Positionierungsoperationen.
   bei System.Net.Sockets.NetworkStream.Seek(Int64 Offset, SeekOrigin Origin)
   bei System.IO.BufferedStream.FlushRead()
   bei System.IO.BufferedStream.WriteByte(Byte Wert)

Der folgende Link zeigt, dass dies ein bekanntes Problem für Microsoft ist. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=273186

Dieser Stacktrace zeigt 2 Dinge:

  1. Der System.IO.BufferedStream führt Operationen mit absurdem Zeiger durch. Ein BufferedStream sollte den zugrunde liegenden Stream puffern und nicht mehr. Die Qualität des Puffers wird schlecht sein, wenn es solche Positionierungsoperationen gibt.
  2. Es wird nie stabil mit einem Stream funktionieren, der keine Positionierungsoperationen unterstützt.

Gibt es Alternativen? Muss ich einen Puffer zusammen mit einem NetworkStream in C# verwenden oder ist dies bereits gepuffert?

Bearbeitung: Ich möchte einfach die Anzahl der Lese-/Schreibaufrufe auf dem zugrunde liegenden Socket-Stream reduzieren.

2voto

pipTheGeek Punkte 2663

Der NetworkStream ist bereits gepuffert. Alle empfangenen Daten werden in einem Puffer gespeichert, der darauf wartet, von Ihnen gelesen zu werden. Aufrufe von read werden entweder sehr schnell sein oder blockieren, während auf Daten vom anderen Teilnehmer im Netzwerk gewartet wird. Ein BufferedStream wird in beiden Fällen nicht helfen.

Wenn Sie sich über das Blockieren Sorgen machen, können Sie in Betracht ziehen, den zugrunde liegenden Socket auf den nicht-blockierenden Modus umzustellen.

1voto

Marc Gravell Punkte 970173

Ein BufferedStream dient einfach dazu, die Anzahl der Lese-/Schreibaufrufe an den zugrunde liegenden Stream (der möglicherweise an die IO/Hardware gebunden ist) zu reduzieren. Es bietet keine Suchfunktion (und tatsächlich sind Puffern und Suchen in vielerlei Hinsicht konträr zueinander).

Warum müssen Sie suchen? Kopieren Sie den Stream vielleicht zuerst in etwas Suchbares - einem MemoryStream oder einem FileStream - und führen Sie dann Ihre tatsächliche Arbeit aus diesem zweiten, suchbaren Stream aus.

Haben Sie einen spezifischen Zweck im Sinn? Ich könnte mit weiteren Details möglicherweise geeignetere Optionen vorschlagen...

Insbesondere: Beachten Sie, dass ein NetworkStream eine Besonderheit darstellt - bei den meisten Streams stehen Lese- und Schreibvorgänge in Bezug auf denselben physischen Stream; bei einem NetworkStream repräsentiert dies jedoch tatsächlich zwei völlig unabhängige Leitungen. Ebenso können Sie sich nicht zu Bytes vorbewegen, die bereits an Ihnen vorbeigeeilt sind... Sie können Daten überspringen, aber das ist besser, indem Sie einige Read-Vorgänge durchführen und die Daten verwerfen.

1voto

Simon Thum Punkte 555

Die Lösung besteht darin, zwei unabhängige BufferedStreams zu verwenden, einen zum Empfangen und einen zum Senden. Und vergessen Sie nicht, den sendenden BufferedStream entsprechend zu leeren.


Da es selbst im Jahr 2018 anscheinend schwer ist, eine zufriedenstellende Antwort auf diese Frage zu bekommen, hier sind meine zwei Cent:

Der NetworkStream wird auf der OS-Seite gepuffert. Das bedeutet jedoch nicht, dass es keine Gründe gibt, auf der .net-Seite zu puffern. TCP verhält sich gut beim Schreiben-Lesen (wiederholen), aber hängt beim Schreiben-Schreiben-Lesen aufgrund von verzögerten ACKs usw.

Wenn Sie, wie ich, eine Menge unterdurchschnittlichen Protokollcode ins einundzwanzigste Jahrhundert bringen möchten, möchten Sie puffern.

Alternativ, wenn Sie sich an das oben Gesagte halten, könnten Sie auch nur Lesevorgänge/Erhaltene oder nur Schreibvorgänge/Sendungen puffern und den NetworkStream direkt für die andere Seite verwenden, je nachdem, wie fehlerhaft der Code ist. Sie müssen nur konsistent sein!

Was die Dokumente zu BufferedStream nicht klar genug machen, ist, dass Sie nur das Lesen und Schreiben umschalten sollten, wenn Ihr Stream verschiebbar ist. Dies liegt daran, dass es Lese- und Schreibvorgänge im selben Puffer puffert. BufferedStream funktioniert einfach nicht gut für NetworkStream.

Wie Marc angemerkt hat, liegt die Ursache für diese Schwäche in der Verschmelzung von zwei Streams in einen NetworkStream, was nicht eine der besten Designentscheidungen von .net ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X