シリアル化でProtoBufferオブジェクトを圧縮し、デシリアライズ時に解凍します。残念なことに、C#stdlibはbyte []ではなくストリームで動作する圧縮ルーチンしか提供していないため、関数呼び出しよりも冗長ではありません。現在までのコード:MemoryStreamsとGZipStreamsを取り除く
class MyObject{
public string P1 {get; set;}
public string P2 {get; set;}
// ...
public byte[] Serialize(){
var builder = new BinaryFormat.MyObject.Builder();
builder.SetP1(P1);
builder.SetP2(P2);
// ...
// object is now build, let's compress it.
var ms = new MemoryStream();
// Without this using, the serialisatoin/deserialisation Tests fail
using (var gz = new GZipStream(ms, CompressionMode.Compress))
{
builder.Build().WriteTo(gz);
}
return ms.ToArray();
}
public void Deserialize(byte[] data)
{
var ms = new MemoryStream();
// Here, Tests work, even when the "using" is left out, like this:
(new GZipStream(new MemoryStream(data), CompressionMode.Decompress)).CopyTo(ms);
var msg = BinaryFormat.MachineInfo.ParseFrom(ms.ToArray());
P1 = msg.P1;
P2 = msg.P2;
// ...
}
}
ストリームを扱うときは、手動でオブジェクトの廃棄を処理する必要があるようです。私はそれがなぜ、私はGZipStreamが完全に管理されたコードになると思うのだろうかと思います。 Deserializeがうまく動作しない場合や、MemoryStreamを処分する必要があるかどうかは不思議です。
私はおそらく、単にこのパーティーの圧縮ライブラリを使用してこの問題を解決することができますが、それはこの質問のポイントの外にある程度です。
オブジェクトを所有しているときに 'MemoryStream'が処分されていることを覚えていれば、' GZipStream'が配置されます。それは単に 'Image'sのためだけかもしれません... – TheLethalCoder
何かが' IDisposable'を実装しているなら、理想的には 'using'を使って処理する必要があります。オブジェクトを正しく使い、処分するためのコードを書くと、まず問題を見たことがないでしょう。 – TheLethalCoder
@TheLethalCoder [必ずしもそうではありません](https://blogs.msdn.microsoft.com/pfxteam/2012/03/25/do-i-need-to-dispose-of-tasks/)、たとえば「タスク」を取るそれはIDisposableですが、関数のページには[あなたはそれをする必要はありません]と書かれています(https://msdn.microsoft.com/en-us/library/dd270681(v = vs.110).aspx#Anchor_2 ).NET 4.5以降を対象とする場合。 –