2009-08-27 5 views
7

Когда .NET BinaryFormatter используется для сериализации графа объектов, применяется ли какой-либо тип сжатия?Использует ли BinaryFormatter любое сжатие?

Прошу в контексте того, должен ли я беспокоиться о графе объектов, имеющем много повторяющихся строк и целых чисел.

Редактировать - Удерживать, если строки интернированы в .NET, вам не нужно беспокоиться о повторяющихся строках, не так ли?

+0

Примитивы счастливо повторяются ad nauseam, единственное «сжатие», которое происходит, состоит в том, что непрерывные последовательности нулей (например, в массиве) сохраняются в виде байтов или целых чисел, представляющих число в последовательности. Строки (обычно) не повторяются, определения классов не повторяются, а множественные ссылки на объекты не приводят к тому, что объект сериализуется/выводится несколько раз. – Tao

ответ

10

Нет, он не обеспечивает никакого сжатия, но вы можете сжать выход самостоятельно, используя тип GZipStream.

Редактировать:Mehrdad имеет прекрасный пример этой техники в своем ответе How to compress a .net object instance using gzip.

Edit 2: Строки могут быть интернированы, но это не означает, что каждая строка является интернированы. Я бы не делал никаких предположений о том, как и почему CLR решает ставить строки, поскольку это может измениться (и изменилось) с версии на версию.

4

Нет, это не так, но ...

Я просто добавил поддержку GZipStream для моего приложения сегодня, так что я могу поделиться некоторый код здесь;

Сериализация:

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); 
     } 
    } 
} 

Десериализация:

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); 
     } 
    } 
} 

Примечание: если вы используете CryptoStream, это своего рода важно, что вы цепи (не) проносясь и (де) криптование право таким образом, потому что вы хотите потерять свою энтропию ПЕРЕД шифрованием создает шум из ваших данных.