J'utilise la bibliothèque de sérialisation Boost, qui est en fait assez agréable, et me permet de faire des emballages simples pour sauver mes objets sérialisables à cordes, comme ceci:Comment connecter une sérialisation Boost & iostreams pour sérialiser & gzip un objet en chaîne?
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;
}
La chose est, je viens de trouver la J'ai aussi besoin de compresser mes données sérialisées, donc je cherche à le faire avec les filtres de boost :: iostreams. J'ai compris comment le faire avec succès avec des fichiers:
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;
}
Mais ne peut pas comprendre comment enregistrer correctement à une chaîne compressée. Le problème est que je ne vidange pas la chaîne de filtres, mais j'ai essayé de sauter et de synchroniser et rien ne semble fonctionner. Voici mon code cassé:
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();
}
En conséquence, certaines données se coince dans le tampon de flux quelque part, et je finis toujours avec aa quelques blocs complets (16K ou 32K) de données compressées quand je sais que ce doit être 43K ou alors donné la sortie (valide) que j'obtiens en utilisant ma méthode saveGZFile. Apparemment, accrocher l'ofstream se ferme et se rince correctement, mais pas l'ostringstream.
Une aide? (Ceci est ma première question stackoverflow - aidez-moi, les gars, vous êtes mon seul espoir!)
Vous pouvez éviter le truc de limitation de portée avec un appel à flush(). f.flush() –
dans le code qui ne fonctionne pas dans ma question, le commentaire dit "' 'oss.flush() ??' "car l'appel' flush() 'sur' ostringstream' ne fonctionnait pas. le truc de limitation de portée est la seule chose qui a fonctionné pour moi. sauf si vous voulez dire que je devrais flush 'f', qui n'a pas de méthode flush (il a une méthode' strict_sync() 'qui est supposée appeler' flush() 'sur tous les périphériques du pipeline, ce que j'ai aussi essayé, en vain). – cce
Merci pour cela - je courais dans le même problème. Aucun vidage disponible et strict_sync n'a eu d'effet. – erikreed