Boost Binary Serialization Problem
I have a problem using boost serialization using binary archives. It works when using a file stream but I want to store it in开发者_Go百科 my local variable and ultimately save/load it to/from berkeley db. When executing the program I get a boost::archive::archive_exception: 'stream error' when instantiating the binary_iarchive.
#include <sys/time.h>
#include <string>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>
#include <sstream>
namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive & ar, timeval & t, const unsigned int version)
{
ar & t.tv_sec;
ar & t.tv_usec;
}
}//namespace serialization
}//namespace boost
int main(int, char**)
{
timeval t1;
gettimeofday(&t1, NULL);
char buf[256];
std::stringstream os(std::ios_base::binary| std::ios_base::out| std::ios_base::in);
{
boost::archive::binary_oarchive oa(os, boost::archive::no_header);
oa << t1;
}
memcpy(buf, os.str().data(), os.str().length());
if(memcmp(buf, os.str().data(), os.str().length()) != 0)
printf("memcpy error\n");
timeval t2;
{
std::stringstream is(buf, std::ios_base::binary| std::ios_base::out| std::ios_base::in);
boost::archive::binary_iarchive ia(is, boost::archive::no_header);
ia >> t2;
}
printf("Old(%d.%d) vs New(%d.%d)\n", t1.tv_sec, t1.tv_usec, t2.tv_sec, t2.tv_usec);
return 0;
}
It works when initializing is with os.str(), so I guess my way of copying the data to my buffer or to is is wrong.
Well, for one thing .data() doesn't have a terminal \0. It's not a c-string. I didn't even realize stringstream had a char* constructor (who in their right mind uses them anymore?) but apparently it does and I'd bet it expects \0.
Why are you trying to do it that way anyway? You're much better off working in C++ strings. Initialize is with os.str().
Edit: binary data contains lots of \0 characters and the std::string(char*) constructor stops at the first one. Your deserialization routine will then inevitably try to read past the end of the stream (because it isn't complete). Use the iterator constructor for std::string when you pass buf into the stringstream.
std::stringstream is(std::string(buf, buf+os.str().length()), flags);
精彩评论