Boost имеет множество полезных библиотек. И хотя многие возражают против использования его в серъезных коммерческих проектах, но тяжело переоценить удобство использования библиотек boost.
В процессе работы возникла задача сериализации данных некой структуры с последующим сохранением их в файл. ИМХО, для таких задач просто отлично подходит boost::serialization.
Ниже будут некоторые примеры работы с данной библиотекой. Более детально можно ознакомиться с ней на boost.org(boost::serialization)
Приступим. Есть структура.
struct SomeData { std::string dataName; std::string dataOwner; uint32 dataSize; }
Чтобы сериализовать данные, используя boost нам необходимо сделать в ней несколько дополнительных
объявлений.
Во-первых, структура должна быть friend class boost::serialization::access.
А во-вторых, она должна иметь метод serialize
// When the class Archive corresponds to an output archive, the // & operator is defined similar to <<. Likewise, when the class Archive // is a type of input archive the & operator is defined similar to >>. template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & smthing; }
Итого результат:
struct SomeData { friend class boost::serialization::access;std::string dataName; std::string dataOwner; uint32 dataSize;template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & dataName; ar & dataOwner; ar & dataSize; } }
Посмотрим как это все работает
Для использования boost::serialization в проекте нам необходимо подключить(так говорит пример).
#include <boost/archive/tmpdir.hpp>#include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_oarchive.hpp>#include <boost/serialization/base_object.hpp> #include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/assume_abstract.hpp>
Для того, чтобы сохранить данные в файл нам необходимо написать 3 строчки:
// Structure to serializationSomeData data; data.dataName = "simple data"; data.dataOwner = "Bill"; data.dataSize = 100;// Create data file std::ofstream resultFile("dataFile.bin"); boost::archive::text_oarchive oa(resultFile); oa << data;
По итогу получаем файл со следующими данными
22 serialization::archive 5 0 0 11 simple data 4 Bill 100
Не очень читабельно, особенно для больших объемов информации. Поэтому есть возможность легко
сохранить данные в *.xml файл. Для этого импользуем макрос BOOST_SERIALIZATION_NVP.
Во-первых, добавляем еще один include:
#include <boost/archive/xml_oarchive.hpp>
Во-вторых, изменится наша структура:
struct SomeData { friend class boost::serialization::access;std::string dataName; std::string dataOwner; uint32 dataSize;template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & BOOST_SERIALIZATION_NVP(dataName); ar & BOOST_SERIALIZATION_NVP(dataOwner); ar & BOOST_SERIALIZATION_NVP(dataSize); } }
Во-вторых еще раз, используем не text_oarchive, а xml_oarchive.
boost::archive::text_oarchive oa(resultFile); oa << BOOST_SERIALIZATION_NVP(data);
Результатом работы такого кода будет:
<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes” ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature=”serialization::archive” version=”5″>
<data class_id=”0″ tracking_level=”0″ version=”0″>
<dataName>simple data</dataName>
<dataOwner>Bill</dataOwner>
<dataSize>100</dataSize>
</data>
</boost_serialization>
Чтобы вычитать данные из файла делаем обратные действия:
std::ifstream inFile("dataFile.xml"); boost::archive::xml_iarchive ia(inFile); ia >> BOOST_SERIALIZATION_NVP(data);
Также boost поддерживает некоторые из стандартных контейнеров, хотя для массивов(векторов) приходится сериализовать каждый элемент.