Я использую библиотеку подталкивания сериализации, который на самом деле очень приятно, и позволяет мне сделать простые обертки, чтобы сохранить свои сериализуемые объекты в строки, например:Как подключить сериализацию Boost и iostreams для сериализации и gzip объекта в строку?
namespace bar = boost::archive;
namespace bio = boost::iostreams;
template <class T> inline std::string saveString(const T & o) {
std::ostringstream oss;
bar::binary_oarchive oa(oss);
oa << o;
return oss.str();
}
template <class T> inline void saveFile(const T & o, const char* fname) {
std::ofstream ofs(fname, std::ios::out|std::ios::binary|std::ios::trunc);
bar::binary_oarchive oa(ofs);
oa << o;
}
template <class T> inline void loadFile(T & o, const char* fname) {
std::ifstream ifs(fname, std::ios::in|std::ios::binary);
assert(ifs.good()); // XXX catch if file not found
bar::binary_iarchive ia(ifs);
ia >> o;
}
Дело в том, я просто нашел нужно также сжать мои сериализованные данные, поэтому я смотрю на это с помощью фильтров в boost :: iostreams. Я понял, как это сделать с файлами:
template <class T> inline void saveGZFile(const T & o, const char* fname) {
std::ofstream ofs(fname, std::ios::out|std::ios::binary|std::ios::trunc);
bio::filtering_streambuf<bio::output> out;
out.push(boost::iostreams::gzip_compressor());
out.push(ofs);
bar::binary_oarchive oa(out);
oa << o;
}
template <class T> inline void loadGZFile(T & o, const char* fname) {
std::ifstream ifs(fname, std::ios::in|std::ios::binary);
assert(ifs.good()); // XXX catch if file not found
bio::filtering_streambuf<bio::input> in;
in.push(bio::gzip_decompressor());
in.push(ifs);
bar::binary_iarchive ia(in);
ia >> o;
}
Но не могу понять, как правильно сохранить сжатую строку. Проблема в том, что я не смываю цепочку фильтров, но я пробовал выскакивать и синхронизировать, и ничего не работает. Вот мой сломанный код:
template <class T> inline std::string saveGZString(const T & o) {
std::ostringstream oss;
bio::filtering_streambuf<bio::output> out;
out.push(bio::gzip_compressor());
out.push(oss);
bar::binary_oarchive oa(out);
oa << o;
// XXX out.pop() twice? out.strict_sync()?? oss.flush()??
return oss.str();
}
В результате некоторые данные застревает в буфер потока где-нибудь, и я всегда в конечном итоге с аа несколько полных блоков (16К или 32К) из сжатых данных, когда я знаю, что это должно быть 43K или так дано (действительный) вывод, который я получаю от использования моего метода saveGZFile. По-видимому, подключение вверх по течению закрывается и прилипает должным образом, но соединение с ним не происходит.
Любая помощь? (Это мой первый StackOverflow вопрос - помогите мне, ребята, ты моя единственная надежда!)
Вы можете избежать трюка ограничения области с вызовом flush(). f.flush() –
в нерабочем коде в моем вопросе, в комментарии говорится «' oss.flush() ?? '", потому что вызов 'flush()' в 'ostringstream' не работал. трюк ограничения объема - единственное, что сработало для меня. если вы не имеете в виду, что я должен очищать 'f', который не имеет метода flush (он имеет метод' strict_sync() ', который должен вызывать' flush() 'на каждом устройстве в конвейере, которое также я пытался, но безрезультатно). – cce
Спасибо за это - я столкнулся с той же проблемой. Отсутствие флеша и strict_sync не повлияло. – erikreed