Сериализовать объект до наименьшего размера, совместимого с UTF8

#c# #serialization #utf-8

#c# #сериализация #utf-8

Вопрос:

У меня есть довольно простой класс, который содержит несколько примитивных типов и несколько коллекций, содержащих в основном перечисления. Теперь мне нужно сериализовать этот объект до минимально возможного размера, совместимого с UTF8.

Это класс, который мне нужно сериализовать

 public class Context
{
    public Hashtable UserModuleRoles { get; set; }
    public Dictionary<string, object> CustomSettings { get; set; }
    public int Uid { get; set; }
    public int Id { get; set; }
    public int ActiveId { get; set; }
    public byte Default { get; set; }
    public SetEnum Ident { get; set; }
    public string Name { get; set; }
    public sbyte State { get; set; }
    public DateTime Date { get; set; }
}
  

.

Вот как я сериализую объект

 public string Serialize(object serializeObject)
{
    MemoryStream stream = new MemoryStream();
    BinaryFormatter b = new BinaryFormatter();

    b.Serialize(stream, serializeObject);

    byte[] data = stream.ToArray();

    stream.Dispose();
    stream = new MemoryStream();

    using (ZipFile zip = new ZipFile())
    {
        zip.AddEntry("data", data);
        zip.Save(stream);
    }

    data = stream.ToArray();
    stream.Dispose();

    return Convert.ToBase64String(data);
}
  

В моей первой попытке я сериализую объект, заархивирую это содержимое (примерно на 1/3 меньше) и преобразую его в строку base64. Но у base64 довольно большие накладные расходы в 1/3, и я знаю, что есть base128, но я не знаю, с чего начать, и мой поиск кодировки base128 оказался безуспешным.

  • Или есть какой-либо другой способ сделать это?

  • И если нет, то каков наилучший способ
    сделать это как base128?

Редактировать:

Я тестировал класс ObjectStateFormatter со всем объектом «Context», что приводит к увеличению на 8 байт и замедлению сериализации / десериализации. Может быть, мне нужно было использовать это только для свойств, а не для всего класса?

Комментарии:

1. Что вы имеете в виду, «совместимый с UTF-8»?

2. Результат будет сохранен в файле cookie, и, насколько я знаю, UTF-8 здесь является стандартом

Ответ №1:

Что ж, base128 не так уж и сложно, если вы знаете, как выполняется base64. Голландская википедия хорошо описывает процесс (перевела его для вас):

  1. Преобразовать данные в двоичный файл.
  2. Продолжайте брать фрагменты по 7 бит (2 ^ 7 = 128)
  3. Преобразуйте эти 7 бит в целое число.
  4. Найдите это целое число в таблице перевода, которую вы определили, и добавьте найденный символ к строке base128.

Эта таблица перевода содержит 128 совместимых символов UTF8, например:

 0: a
1: b
..
25: z
26: 0
  

Единственное требование заключается в том, чтобы таблица перевода была одинаковой как у отправителя, так и у получателя.

Комментарии:

1. Спасибо! Это поможет мне в этом случае. Но все еще остается вопрос, является ли это лучшим решением или если есть лучшее.

2. Мы не можем сказать вам, является ли это «лучшим решением», с которым вы не предоставили нам достаточно для работы.

3. Хорошо, я опубликовал код метода serialize и класс для сериализации. Я не знаю, что еще вы имеете в виду.

Ответ №2:

Попробуйте использовать objectstateformatter вместо BinaryFormatter , возможно, это даст вам меньший размер. Все зависит от данных, которые вы сериализуете.

Комментарии:

1. Хорошо, я попробую это завтра и сравню размер. Самой большой частью будет хэш-таблица, которая содержит только перечисления. Или, может быть, не самый большой, но часть с наибольшим количеством значений.

2. Хорошо, наконец-то я это протестировал. В моем простом тесте он был примерно на 8 байт больше обычного потока байтов и намного медленнее. Я не знаю почему, потому что все типы данных внутри объекта полностью совместимы с классом objectstateformatter, согласно msdn. Возможно, я получу лучшие результаты, если я сериализую только значения и ничего из объекта. Но тогда я окажусь в более чем десяти отдельных потоках и … нет, для меня это звучит не очень хорошо. Или я что-то пропустил в своем тесте?