używam biblioteki serializacji doładowania, co jest rzeczywiście bardzo ładny, i pozwala mi wykonywać proste owijarki, aby zapisać swoje serializacji obiektów do strun, tak jak poniżej:Jak podłączyć Wzmocnienie serializacji i iostreams do serializacji i gzip obiektu do napisu?
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;
}
Chodzi o to, po prostu okazało się, że muszę również skompresować moje zserializowane dane, więc szukam tego z filtrami w boost :: iostreams. Pomyślałem, jak to zrobić z powodzeniem z plikami:
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;
}
Ale nie mogę dowiedzieć się, jak poprawnie zapisać skompresowany ciąg. Problem polega na tym, że nie przepłukiwam łańcucha filtrów, ale próbowałem robić popping i synchronizować i nic nie działa. Oto mój złamany kod:
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();
}
W rezultacie niektóre dane utknie w buforze strumienia gdzieś, a ja zawsze skończyć z aa kilku kompletnych bloków (16K lub 32K) skompresowanych danych, gdy wiem, że powinien on być 43K lub tak, biorąc pod uwagę (poprawne) dane wyjściowe otrzymuję z wykorzystaniem mojej metody saveGZFile. Wygląda na to, że podpięcie się zamyka i spłukuje, ale podpięcie ostringstream nie.
Każda pomoc? (To jest moje pierwsze pytanie stackoverflow - pomóż mi, chłopaki, jesteś moją jedyną nadzieją!)
Możesz uniknąć sztuczki z ograniczeniem zasięgu za pomocą wywołania flush(). f.flush() –
w niepracującym kodzie w moim pytaniu, komentarz mówi "' oss.flush() ?? '" ponieważ wywołanie 'flush()' na 'ostringstream' nie działało. sztuczka z ograniczeniem zasięgu jest jedyną rzeczą, która zadziałała dla mnie. chyba że masz na myśli, że powinienem wypróżnić 'f', który nie ma metody flush (ma metodę' strict_sync() ', która powinna wywoływać' flush() 'na każdym urządzeniu w potoku, które również próbowałem, bez skutku). – cce
Dzięki za to - natknąłem się na ten sam problem. Brak opcji spłukiwania, a strict_sync nie ma żadnego efektu. – erikreed