[C#]シリアライズしたバイナリデータを圧縮解凍する方法

.Net Freamework 2.0から、System.IO.Compressionが追加されていて、DeflateStream(rfc1951), GZipStream(rfc1952)が使用できる。
シリアライズはBinaryFormatterを使えばいい。簡単に書こうとすると、以下のよーな感じになる。

/// <summary>
/// オブジェクトを圧縮して書き込み
/// </summary>
/// <param name="filePath"></param>
/// <param name="obj"></param>
public void WriteWithCompress(string filePath, object obj)
{
    using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
    {
        using (DeflateStream ds = new DeflateStream(stream, CompressionMode.Compress, true))
        {
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ds, obj);
        }
    }
}

このソースを.Net Freamework 2.0(VisualStudio2005)で動作させてみると、出力サイズが大して圧縮されていないことに気づくと思う。ところが、.Net Freamework 3.0(VisualStudio2008)で動作させるとサイズは半分以下になる。
この違いは、恐らく2.0のバグが3.0で改善されたとか、そんなところじゃないかと思われる。根拠はないが。
じゃあ2.0では使い物にならないのかというと、そういうわけでもない。
MemoryStreamを使用して、逐一バッファに保持すればいい。

/// <summary>
/// オブジェクトを圧縮して書き込み
/// </summary>
/// <param name="filePath"></param>
/// <param name="obj"></param>
public void WriteWithCompress(string filePath, object obj)
{
    byte[] buffer;
    using (MemoryStream ms = new MemoryStream())
    {
        IFormatter formatter = new BinaryFormatter();
        formatter.Serialize(ms, obj);
        buffer = ms.ToArray();
    }
    using (MemoryStream ms = new MemoryStream())
    {
        using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress, true))
        {
            ds.Write(buffer, 0, buffer.Length);
        }
        buffer = ms.ToArray();
    }
    using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
    {
        stream.Write(buffer, 0, buffer.Length);
    }
}

これで2.0, 3.0で同様の結果が得られる。
読み込みについては、バージョン関係なく以下のように。

/// <summary>
/// 圧縮されたオブジェクトを解凍して読み込み
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public object ReadWithDecompress(string filePath)
{
    object obj;
    using (Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    {
        using (DeflateStream ds = new DeflateStream(stream, CompressionMode.Decompress))
        {
            IFormatter formatter = new BinaryFormatter();
            obj = formatter.Deserialize(ds);
        }
    }
    return obj;
}

ちなみに、GZipStreamを使いたい場合は、DeflateStreamをGZipStreamに書き換えるだけでOKだ。