Late answer but going to answer it anyways. If you understand how it works you can understand why it makes no sense to use in some cases and why it makes sense to not use in other cases.
To proof this I am using StreamWrapper
class. Only use this class to see how many times you hit a breakpoint! Place breakpoints all over this class. Our goal is to see how many times we call the Write, Read, and other methods.
// This class is only used for demo purposes. Place a breakpoint on all parts
class StreamWrapper : Stream
{
Stream stream;
public StreamWrapper(Stream s)
{
stream = s;
}
public override bool CanRead => stream.CanRead;
public override bool CanSeek => stream.CanSeek;
public override bool CanWrite => stream.CanWrite;
public override long Length => stream.Length;
public override long Position { get => stream.Position; set => stream.Position = value; }
public override void Flush()
{
stream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return stream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return stream.Seek(offset,origin);
}
public override void SetLength(long value)
{
stream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
stream.Write(buffer, offset, count);
}
}
Now that you have that wrapper class that is basically a wrapper to an existing strem you may do the following tests:
Example Writting:
// in real life you want this to be larger.
int bufferSize = 8;
// Use BufferedStream to buffer writes to a MemoryStream.
using (var memory_test = new StreamWrapper(new MemoryStream()))
using (BufferedStream stream = new BufferedStream(memory_test, bufferSize))
{
// all this will only send one write to memory_test!
stream.Write(new byte[] { 1, 2 });
stream.Write(new byte[] { 1, 2 });
stream.Write(new byte[] { 1, 2 });
stream.Write(new byte[] { 1, 2 });
// BREAKPOINT ONLY HITS ONE TIME
// All this will also send only one write to memory_test
for (int i = 0; i < 8; i++)
stream.WriteByte(5);
// BREAKPOINT ONLY HITS ONE TIME AGAIN INSTAD OF 8
// this will send one write to memory_test. Writes of more than 8 bytes can happen!
stream.Write(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 });
// ALL THIS WILL SEND ONE WRITE AGAIN
}
Example reading:
// example reading
{
// create stream with some data in it that we will be reading
var ms = new MemoryStream();
{
// Write 256 bytes
for (int i = 0; i <= byte.MaxValue; i++)
{
ms.WriteByte((byte)i);
}
ms.Position = 0;
}
// Use BufferedStream to buffer writes to a MemoryStream.
using (var memory_test = new StreamWrapper(ms))
{
using (BufferedStream stream = new BufferedStream(memory_test, 8))
{
// note I do not care about the output of each read for demo breakpoint. On real life you will store that output
// for now we only care how many times we hit the breakpoint because on real life that could be a slow/expensive
// operation such as opening a file for writing and you want to do those as few as possible.
// hit breakpoint only one time with all this reads
stream.ReadByte();
stream.ReadByte();
stream.ReadByte();
stream.ReadByte();
stream.ReadByte();
stream.ReadByte();
stream.ReadByte();
stream.ReadByte();
// hit breakpoint only one time with all this reads
stream.Read(new byte[2] );
stream.Read(new byte[2] );
stream.Read(new byte[2] );
stream.Read(new byte[2] );
// hit breakpoint only one time even though it is larger than our buffer size 8
// our goal is to hit the breakpoint as fewest time as possible because in real life
// this could be slow/expensive operations
stream.Read(new byte[1024] );
}
}
}
If this where to be write operations to a file for example performance could increase by ensuring you always write at least 8 bytes instead of 1 at a time. In real life you want this number to be about 4 KB