2009-02-15 4 views
1

Je reçois l'exception suivante:Existe-t-il une alternative à System.IO.BufferedStream en C#?

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) 

Le spectacle de lien de suivi que ce problème est connu pour Microsoft. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=273186

Ce stacktrace spectacle 2 choses:

  1. Le System.IO.BufferedStream faire une opération de déplacement de pointeur absurde. Un BufferedStream doit mettre en tampon le flux sous-jacent et pas plus. La qualité du tampon sera mauvaise s'il y a une telle opération de recherche.
  2. Il ne fonctionnera jamais stable avec un flux qui ne supporte pas Seek.

Y a-t-il des alternatives? Ai-je besoin d'un tampon avec un NetworkStream en C# ou est-ce déjà tamponné?

Modifier: Je veux simplement réduire le nombre d'appels en lecture/écriture dans le flux de socket sous-jacent.

+0

Avez-vous effectué la recherche ou est-ce que cela s'est produit suite à une opération d'écriture? –

+0

Comment vous voyez dans le stacktrace que j'appelle seulement WriteByte(). Le problème est qu'il y a des données dans le tampon de lecture au moment de l'opération d'écriture. – Horcrux7

+0

Vous avez raison - je n'ai pas lu la trace tout le chemin. –

Répondre

1

Un BufferedStream agit simplement pour réduire le nombre d'appels en lecture/écriture dans le flux sous-jacent (qui peut être lié à l'ES/matériel). Il ne peut pas fournir de capacité de recherche (et en effet, la mise en mémoire tampon et la recherche sont à bien des égards contraires l'une à l'autre).

Pourquoi avez-vous besoin de chercher? Peut-être copiez le flux vers quelque chose qui peut être recherché en premier - un MemoryStream ou un FileStream - puis effectuez votre travail réel à partir de ce second flux de recherche.

Avez-vous un but précis en tête? Je pourrais être en mesure de suggérer des options plus appropriées avec plus de détails ...

En particulier: notez que NetworkStream est une curiosité - avec la plupart des flux, lire/écrire se rapportent au même flux physique; cependant, un NetworkStream représente en réalité deux tuyaux complètement indépendants; lire et écrire sont complètement indépendants. De même, vous ne pouvez pas chercher dans les octets qui ont déjà passé devant vous ... vous pouvez ignorer les données, mais cela est mieux fait en faisant quelques opdrations Read et en supprimant les données.

+0

D'abord, vous devriez jeter un coup d'oeil sur la trace. Je veux réduire le nombre d'appels de lecture/écriture au flux sous-jacent. .NET appelle seek() et non I. – Horcrux7

+0

Vous avez raison et je m'excuse. Très, très étrange! –

2

Le NetworkStream est déjà mis en mémoire tampon. Toutes les données reçues sont conservées dans un tampon en attente de votre lecture. Les appels à lire seront soit très rapides, soit bloqueront l'attente de la réception des données de l'autre homologue sur le réseau, un BufferedStream n'aidera pas dans les deux cas.

Si vous êtes préoccupé par le blocage, vous pouvez envisager de basculer le socket sous-jacent en mode non bloquant.