2009-08-27 15 views
7

Quando .NET è BinaryFormatter utilizzato per serializzare un oggetto grafico, è applicato un qualsiasi tipo di compressione?BinaryFormatter applica una compressione?

Chiedo nel contesto se dovrei preoccuparmi del fatto che il grafico dell'oggetto abbia molte stringhe e interi ripetuti.

Modifica - Aspetta, se le stringhe sono internati in .NET, non c'è bisogno di preoccuparsi di stringhe ripetute, giusto?

+0

Le primitive sono felicemente ripetute fino alla nausea, l'unica "compressione" che si verifica è che sequenze ininterrotte di null (ad esempio in una matrice) vengono memorizzate come byte o numeri interi che rappresentano il numero nella sequenza. Le stringhe sono (in genere) non ripetute, le definizioni di classe non vengono ripetute e riferimenti a più oggetti non determinano la serializzazione/emissione di più volte l'oggetto. – Tao

risposta

10

No, non fornisce alcuna compressione ma è possibile comprimere l'output manualmente utilizzando il tipo GZipStream.

Modifica:Mehrdad ha un meraviglioso esempio di questa tecnica nella sua risposta a How to compress a .net object instance using gzip.

Edit 2: stringhe possono essere internati, ma questo non significa che ogni stringa è internati. Non farei alcuna ipotesi su come o perché il CLR decide di stringere internamente in quanto questo può cambiare (ed è cambiato) da versione a versione.

4

No, non è così, ma ...

Ho appena aggiunto il supporto per la mia app GZipStream oggi, in modo da poter condividere un certo codice qui;

serializzazione:

using (Stream s = File.Create(PathName)) 
{ 
    RijndaelManaged rm = new RijndaelManaged(); 
    rm.Key = CryptoKey; 
    rm.IV = CryptoIV; 
    using (CryptoStream cs = new CryptoStream(s, rm.CreateEncryptor(), CryptoStreamMode.Write)) 
    { 
     using (GZipStream gs = new GZipStream(cs, CompressionMode.Compress)) 
     { 
      BinaryFormatter bf = new BinaryFormatter(); 
      bf.Serialize(gs, _instance); 
     } 
    } 
} 

deserializzazione:

using (Stream s = File.OpenRead(PathName)) 
{ 
    RijndaelManaged rm = new RijndaelManaged(); 
    rm.Key = CryptoKey; 
    rm.IV = CryptoIV; 
    using (CryptoStream cs = new CryptoStream(s, rm.CreateDecryptor(), CryptoStreamMode.Read)) 
    { 
     using (GZipStream gs = new GZipStream(cs, CompressionMode.Decompress)) 
     { 
      BinaryFormatter bf = new BinaryFormatter(); 
      _instance = (Storage)bf.Deserialize(gs); 
     } 
    } 
} 

NOTA: se si utilizza CryptoStream, è un po importante catena (dis) zippare e (de) crypting proprio in questo modo, perché ti conviene perdere la tua entropia PRIMA la crittografia crea rumore dai tuoi dati.