GZipStream And DeflateStream will not decompress all bytes

You need to Close() the ZipStream after adding all the data you want to compress; it retains a buffer of unwritten bytes internally (even if you Flush()) that needs to be written.

More generally, Stream is IDisposable, so you should also be using each… (yes, I know that MemoryStream isn’t going to lose any data, but if you don’t get into this habit, it will bite you with other Streams).

public static byte[] Compress(byte[] data)
{
    using (var compressedStream = new MemoryStream())
    using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
    {
        zipStream.Write(data, 0, data.Length);
        zipStream.Close();
        return compressedStream.ToArray();
    }
}

public static byte[] Decompress(byte[] data)
{
    using(var compressedStream = new MemoryStream(data))
    using(var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
    using (var resultStream = new MemoryStream())
    { ... }
}

[edit : updated re comment]
Re not using things like MemoryStream – this is always a fun one, with lots of votes on either side of the fence: but ultimatey…

(rhetorical – we all know the answer…) How is MemoryStream implemented? is it a byte[] (owned by .NET)? is it a memory-mapped file (owned by the OS)?

The reason you aren’t using it is because you are letting knowledge of internal implementation details change how you code against a public API – i.e. you just broke the laws of encapsulation. The public API says: I am IDisposable; you “own” me; therefore, it is your job to Dispose() me when you are through.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)