2010-06-11 58 views
3

我使用二进制档案使用boost序列化时出现问题。它在使用文件流时有效,但我想将其存储在本地变量中,并最终将其保存/加载到/从berkeley db中。 当执行程序时,我得到一个boost :: archive :: archive_exception:当实例化binary_iarchive时出现'流错误'。Boost二进制序列化问题

#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; 
} 

初始化时,它的工作原理是os.str(),所以我想将数据复制到我的缓冲区我的方式或是错误的。

回答

9

那么,有一件事.data()没有终端\ 0。这不是一个C字符串。我甚至没有意识到stringstream有一个char *构造函数(谁在他们正确的心态使用它们了?),但显然它确实,我敢打赌它期望\ 0。

为什么你试图这样做呢?用C++字符串工作会更好。初始化是用os.str()。

编辑:二进制数据包含很多\ 0字符,std :: string(char *)构造函数停在第一个。您的反序列化例程将不可避免地尝试读取流尾(因为它不完整)。将buf传递到stringstream时,使用std :: string的迭代器构造函数。

std::stringstream is(std::string(buf, buf+os.str().length()), flags); 
+0

我已经尝试过使用c-string,但那也不起作用。我不使用C++字符串,因为我需要将原始数据存储在我的berkeley数据库中。这样做的目的是将序列化的数据保存在berkeley数据库中,然后检索并反序列化它。 – user364688 2010-06-11 16:44:58

+3

我是对的。 stringstream没有非字符串构造函数。你的代码试图通过隐式转换创建一个。如果你真的坚持,你可以通过传递std :: string(buf,buf + os.str()。length())来代替buf来显式地进行转换。这应该解决你的问题,因为std :: string的char *构造函数将停止在它发现的* first * \ 0处,并且你的二进制数据可能与它们混杂在一起。 – 2010-06-11 16:49:22

+0

作品,感谢您的帮助! – user364688 2010-06-11 20:33:08