Простая в использовании расширяемая сериализация/сортировка?

У меня вопрос о сериализации структур данных. Существует множество возможностей сериализации структур данных (также называемых маршаллингом или дефлированием, см. вики-статья). Кажется, что каждый язык программирования, фреймворк, стандарт или библиотека приносят с собой свои собственные методы сериализации. Многие также определяют свой собственный язык описания данных/интерфейса (который я предпочитаю структуре данных, зависящей от языка, определенной только внутри кода). Вот лишь некоторые из них (см. вики-статью): COM IDL, CORBA IDL, Thrift IDL, буфер протокола Google ".proto", XSD, ASN.1 IDL и т. д. Некоторые из этих сериализаций могут генерировать собственную структуру данных языка и код для сериализации и десериализации этих структур.

Я провел некоторое исследование на эту тему, но я все еще не решил. Итак, мой вопрос: Какую сериализацию мне следует использовать?

Мои требования: расширяемость, эффективное использование пространства (по крайней мере, в двоичном виде), эффективный доступ к данным, простота использования (возможно, со сгенерированным кодом и геттерами и сеттерами) и совместимость с C++.

Расширяемость должна обеспечивать прямую и обратную совместимость. Чтобы быть более конкретным, часто форматы данных, которые я пишу, со временем будут расти, потому что я добавляю новые поля данных, которые я не мог предвидеть в начале разработки. Теперь я хотел бы иметь возможность читать сохраненные данные из устаревшего формата с более новой версией программного обеспечения, поля данных, не найденные в старых сохраненных данных, могут быть заполнены значениями по умолчанию или чем-то еще. С другой стороны, я хотел бы иметь возможность читать данные, записанные с новым описанием. Затем поле неизвестных данных должно игнорироваться программным обеспечением, скомпилированным со «старым» описанием данных (возможно, сгенерировав некоторое предупреждение).

Есть ли какие-нибудь рекомендации? Мы также будем признательны за рекомендации по дальнейшему чтению по этому вопросу.

--- Изменить ---

1) boost::serialization кажется довольно популярным. У него есть несколько действительно приятных функций, очень хорошая документация, и синтаксис кажется довольно простым. Может быть, я немного придирчив, но есть некоторые вещи, которые мне не нравятся: я не понимаю, как он может справиться с прямой совместимостью (см. 4). Я бы предпочел сгенерированный код.

2) google protobuf, кажется, лучше соответствует моим потребностям, но я не изучал их глубину. Кажется, они хорошо справляются с прямой и обратной совместимостью (см. 5). У них есть генераторы кода для разных языков, и разработчики знают об очень похожих концепциях, таких как (см. Часто задаваемые вопросы). Я буду глубже изучать protobufs.

3) Boost Spirit, похоже, не то, что я ищу.


person Metaprogger    schedule 24.02.2011    source источник
comment
Да, прямой совместимости, к сожалению, не хватает в boost::serialization. Кроме того, я столкнулся с некоторыми небольшими различиями в XML-файлах, сгенерированных на Mac и ПК в предыдущей версии boost::serialization, поэтому есть сомнения и в полной совместимости с этим форматом. Покопаться в Protobuf кажется лучшей идеей, расскажите, как это было.   -  person Olli Etuaho    schedule 01.03.2011


Ответы (2)


Boost::serialize — это здорово

  • Поддерживает разные версии архива
  • Хорошая поддержка большинства структур данных (указателей, векторов...)
  • Очень быстро (10 секунд для 1Gb, поэтому ограничение - ваш жесткий диск)
  • Довольно прост в использовании
  • Сжатие «на лету» при использовании с boost::iostreams

Недостатки:

  • Архив может быть несовместим с одной платформой для другой
  • Только для C++, без обмена с другими языками

Хорошая альтернатива, которая растет, — это протокольные буферы от Google http://code.google.com/p/protobuf/

  • Независимый от языка
  • Поддержка версий
  • Очень быстро

Поэтому, если вы хотите обмениваться данными между разными системами, я бы выбрал протокольные буферы. Однако, если у вас есть одно приложение, я бы использовал boost::serialize

person Tristram Gräbener    schedule 25.02.2011
comment
Спасибо за ваш ответ. Возможно, у меня будет несколько приложений, обменивающихся данными через сеть, тогда boost::serialize не подходит? - person Metaprogger; 25.02.2011
comment
Boost::serialize имеет множество форматов, таких как двоичный, текстовый или XML. Если вы используете текст или XML, проблем не будет. Тем не менее, двоичный файл может быть проблемой. - person Tristram Gräbener; 25.02.2011

Некоторое время я использовал библиотеку сериализации boost — она хорошо расширяема, эффективна и поддерживает отдельные версии для каждого объекта, который вы сериализуете. Все эти особенности, конечно, означают, что это сложный зверь, и для его правильного изучения требуется некоторое время. Не так быстро компилируется. И если вы когда-нибудь попытаетесь перенести его на платформу, которая официально не поддерживается, ожидайте отладки какого-то очень запутанного кода. Совместимость файлов на разных платформах может быть ненадежной, а прямая совместимость работать не будет. В целом, ускоренная сериализация, как правило, не является хорошим выбором, если вам нужно, чтобы экземпляры приложения взаимодействовали друг с другом. Тем не менее, не все так плохо для правильного проекта.

http://www.boost.org/doc/libs/1_46_0/libs/serialization/doc/index.html

Boost также имеет более новую библиотеку Spirit для более общего синтаксического анализа/вывода, но я не использовал ее и не рекомендовал бы ее на основе первых впечатлений — нужно немного покопаться, чтобы даже понять, для чего предназначена библиотека со своеобразным названием.

В конце концов, для более простых проектов развертывание собственной библиотеки сериализации также может быть неплохим выбором — это не слишком сложно, и вы получаете именно те функции, которые вам нужны. Разочаровывает тот факт, что в мире C++ сериализация до сих пор не решена должным образом, но именно к такому выводу я пришел в прошлый раз, когда мне пришлось выбирать функциональность сериализации. Тем не менее, использование сериализации boost на некоторое время дало хорошее представление о том, к чему стремиться в моей собственной реализации.

person Olli Etuaho    schedule 25.02.2011
comment
+1 за буст :: сериализовать. Boost::spirit предназначен для разбора грамматик. Таким образом, вы можете использовать его для сериализации, но это будет медленно и сложно в обслуживании. - person Tristram Gräbener; 25.02.2011
comment
Да, я только что слышал некоторые смутные упоминания об использовании Spirit для сериализации, но да, вероятно, это не тот инструмент. - person Olli Etuaho; 25.02.2011
comment
Спасибо за ваш ответ. Я слышал о boost::serializton и раньше, но не вникал в него, сделаю сейчас. Может быть, это правильно для меня. - person Metaprogger; 25.02.2011