Há uma alternativa para System.IO.BufferedStream em C #?
-
23-08-2019 - |
Pergunta
Eu recebo a exceção a seguir:
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)
O link seguem mostram que este é um problema conhecido para a Microsoft. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback. aspx? FeedbackID = 273186
Este show stacktrace 2 coisas:
- O System.IO.BufferedStream fazer alguma operação ponteiro movimento absurdo. Um BufferedStream deve tamponar o fluxo subjacente e não mais. A qualidade de tampão vai ser ruim se houver tal operação de busca.
- Ele nunca estável trabalho com um fluxo que não suporta Seek.
Existem alternativas? Será que eu preciso de um tampão junto com um NetworkStream em C # ou se isso já tamponada.
Edit:. Eu quero simplesmente reduzir o número de chamadas de leitura / gravação para o fluxo de soquete subjacente
Solução
A solução é a utilização de dois BufferedStream
s independentes, um para recepção e um para o envio. E não se esqueça de lavar o BufferedStream
envio de forma adequada.
Uma vez que mesmo em 2018 parece difícil obter uma resposta satisfatória para esta questão, para o bem da humanidade, aqui estão meus dois centavos:
O NetworkStream
é tamponada no lado do OS. No entanto, isso não significa que não existem razões para a memória intermédia do lado do .NET. TCP se comporta bem em Write-Read (repetição), mas barracas em Write-Write-Leia devido à ACK atrasado, etc, etc.
Se você, como eu, tem um monte de código do protocolo sub-par para levar para o século XXI, você quer tampão.
Como alternativa , se você ficar com o acima, você poderia também tampão só lê / RCVS ou só escreve / envia, e usar o NetworkStream
diretamente para o outro lado, dependendo de como quebrado o código é . Você apenas tem que ser coerente!
O que docs BufferedStream
não conseguem fazer bem claro é que você deve única interruptor ler e escrever se o seu fluxo é pesquisável . Isso é porque ele buffers lê e escreve no mesmo tampão. BufferedStream
simplesmente não funciona bem para NetworkStream
.
Como Marc apontou, a causa desta claudicação é a fusão de duas correntes em um NetworkStream que não é um dos de .net maiores decisões de projeto.
Outras dicas
O NetworkStream já é tamponado. Todos os dados recebidos é mantido em uma espera de buffer para que você possa lê-lo. Chamadas para ler ou será muito rápido, ou irá bloquear à espera de dados a serem recebidos do outro par na rede, um BufferedStream não vai ajudar em qualquer caso.
Se você está preocupado com o bloqueio, em seguida, você pode olhar para mudar o soquete subjacente ao modo não-bloqueio.
A BufferedStream
simplesmente age para reduzir o número de chamadas de leitura / gravação para o fluxo subjacente (que pode ser IO / hardware ligado). Ele não pode fornecer procuram capacidade (e, na verdade, tamponamento e buscando são, em muitos aspectos contrários um ao outro).
Por que você precisa procurar? copiar, talvez, o fluxo para algo passível de busca em primeiro lugar - um MemoryStream
ou um FileStream
-., em seguida, fazer o seu trabalho real do que o segundo, fluxo pesquisável
Você tem um propósito específico em mente? Eu posso ser capaz de sugerir opções mais apropriadas com mais detalhes ...
Em particular: nota que NetworkStream
é uma curiosidade - com a maioria dos córregos, leitura / gravação se relacionam com o mesmo fluxo físico; no entanto, um NetworkStream
realmente representa dois tubos totalmente independentes; ler e escrever são completamente alheios. Da mesma forma, você não pode procurar em bytes que já compactados por você ... você pode ignorar dados, mas que é melhor feito por fazer algumas opdrations Read
e descartando os dados.