2010-06-11 133 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