C# – Are there an alternative to System.IO.BufferedStream in C#


I receive the follow exception:

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)

The follow link show that this is a known problem for microsoft.

This stacktrace show 2 things:

  1. The System.IO.BufferedStream do some absurd pointer move operation. A BufferedStream should buffer the underlying stream and not more. The quality of buffer will be bad if there are such seek operation.
  2. It will never work stable with a stream that not support Seek.

Are there any alternatives?
Does I need a buffer together with a NetworkStream in C# or is this already buffered.

Edit: I want simply reduce the number of read/write calls to the underlying socket stream.

Best Solution

The solution is to use two independent BufferedStreams, one for receiving and one for sending. And don't forget to flush the sending BufferedStream appropriately.

Since even in 2018 it seems hard to get a satisfying answer to this question, for the sake of humanity, here are my two cents:

The NetworkStream is buffered on the OS side. However, that does not mean there are no reasons to buffer on the .net side. TCP behaves well on Write-Read (repeat), but stalls on Write-Write-Read due to delayed ack, etc, etc.

If you, like me, have a bunch of sub-par protocol code to take into the twentyfirst century, you want to buffer.

Alternatively, if you stick to the above, you could also buffer only reads/rcvs or only writes/sends, and use the NetworkStream directly for the other side, depending on how broken what code is. You just have to be consistent!

What BufferedStream docs fail to make abundantly clear is that you should only switch reading and writing if your stream is seekable. This is because it buffers reads and writes in the same buffer. BufferedStream simply does not work well for NetworkStream.

As Marc pointed out, the cause of this lameness is the conflation of two streams into one NetworkStream which is not one of .net's greatest design decisions.