Ich möchte ein ProtoBuffer-Objekt bei der Serialisierung komprimieren und bei der Deserialisierung dekomprimieren. Unglücklicherweise bietet C# stdlib nur Komprimierungsroutinen, die auf Streams und nicht auf Byte [] arbeiten, was es ein bisschen unessery verböser macht als einen Funktionsaufruf. Mein bisheriger Code:Disponieren von MemoryStreams und 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;
// ...
}
}
Beim Umgang mit Streams scheint es, dass man sich manuell um die Entsorgung der Objekte kümmern muss. Ich frage mich, warum das so ist, ich würde erwarten, dass GZipStream vollständig verwaltet wird. Und ich frage mich, ob Deserialize nur durch Zufall funktioniert und ob ich die MemoryStreams auch entsorgen sollte.
Ich weiß, dass ich dieses Problem wahrscheinlich lösen könnte, indem ich einfach eine dritte Partei Kompressions-Bibliothek verwende, aber das ist etwas neben dem Punkt dieser Frage.
Wenn ich mich recht erinnere, wird ein 'MemoryStream' entsorgt, wenn es ein Objekt besitzt, in diesem Fall wird der' GZipStream' entsorgt. Oder das könnte nur für 'Image's ... sein. – TheLethalCoder
Nun nimm es als Lernkurve, wenn etwas' IDisposable' implementiert, sollte es entsorgt werden, idealerweise mit 'using'. Schreiben Sie Code, um Objekte ordnungsgemäß zu verwenden und zu entfernen, und Sie hätten das Problem von Anfang an nicht erkannt. – TheLethalCoder
@TheLethalCoder [nicht immer] (https://blogs.msdn.microsoft.com/pfxteam/2012/03/25/do-i-need-to-dispose-of-tasks/), nehmen Sie 'Task' zum Beispiel Es ist IDisposeable, aber es ist Seite für die Funktion sagt [Sie müssen es nicht tun] (https://msdn.microsoft.com/en-us/library/dd270681 (v = vs.110) .aspx # Anchor_2), wenn .NET 4.5 oder höher als Targeting verwendet wird. –