You can't copy the stream to itself, at least not without a lot of work. Just allocating a new MemoryStream for the compressed data is simple and reasonably efficient. eg
public MemoryStream GZipCompress(MemoryStream memoryStream)
{
var newStream = new MemoryStream((int)memoryStream.Length / 2); //set to estimate of compression ratio
using (GZipStream compress = new GZipStream(newStream, CompressionMode.Compress))
{
memoryStream.CopyTo(compress);
}
newStream.Position = 0;
return newStream;
}
Here's an untested idea for how to perform in-place compression of a MemoryStream.
public void GZipCompress(MemoryStream memoryStream)
{
var buf = new byte[1024 * 64];
int writePos = 0;
using (GZipStream compress = new GZipStream(memoryStream, CompressionMode.Compress))
{
while (true)
{
var br = compress.Read(buf, 0, buf.Length);
if (br == 0) //end of stream
{
break;
}
var readPos = memoryStream.Position;
memoryStream.Position = writePos;
memoryStream.Write(buf, 0, br);
writePos += br;
if (memoryStream.Position > readPos)
{
throw new InvalidOperationException("Overlapping writes corrupted the stream");
}
memoryStream.Position = readPos;
}
}
memoryStream.SetLength(writePos);
memoryStream.Position = 0;
}