使用Boost序列化库反序列化时遭遇输入流错误问题求助
Boost序列化非默认构造函数类时出现"input stream error"异常
我使用Boost序列化库对带有非默认构造函数的类进行序列化操作,序列化过程正常,但反序列化读取文件时抛出input stream error异常。已参考官方文档实现,尝试移除Book类serialize方法中的ar & name(文档示例同样如此),但仍报错。调试发现异常来自load_access类的load_primitive函数。
源码
#include <fstream> #include <filesystem> #include <boost/serialization/access.hpp> #include <boost/serialization/string.hpp> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> class Book { private: std::string name; friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int file_version) { ar & name; } public: Book(std::string name): name(name) {} }; namespace boost { namespace serialization { template<class Archive> inline void save_construct_data(Archive& ar, Book* book, const unsigned int file_version) { ar << book->name; } template<class Archive> inline void load_construct_data(Archive& ar, Book* book, const unsigned int file_version) { std::string name; ar >> name; ::new(book)Book(name); } } } int main() { Book book("Harry Potter"); std::ofstream ofs("Book.txt"); boost::archive::text_oarchive oa(ofs); oa << &book; ofs.close(); Book* read; std::ifstream ifs("Book.txt", std::ios::binary); boost::archive::text_iarchive ia(ifs); ia >> read; ifs.close(); }
错误信息
terminate called after throwing an instance of 'boost::archive::archive_exception' what(): input stream error
问题原因及解决办法
核心问题
- 文本归档与二进制打开模式冲突:使用
text_oarchive生成的是文本格式归档,但反序列化时用std::ios::binary打开输入流,导致文本内容被错误解析,直接触发输入流异常。 - 重复序列化成员变量:
save_construct_data已序列化name,serialize方法又再次序列化该变量,造成归档内容冗余,反序列化时数据不匹配。
修正后的代码
#include <fstream> #include <iostream> #include <filesystem> #include <boost/serialization/access.hpp> #include <boost/serialization/string.hpp> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> class Book { private: std::string name; friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int file_version) { // 移除重复的name序列化,构造数据已处理该字段 } public: Book(std::string name): name(name) {} const std::string& get_name() const { return name; } }; namespace boost { namespace serialization { template<class Archive> inline void save_construct_data(Archive& ar, Book* book, const unsigned int file_version) { ar << book->name; } template<class Archive> inline void load_construct_data(Archive& ar, Book* book, const unsigned int file_version) { std::string name; ar >> name; ::new(book)Book(name); } } } int main() { Book book("Harry Potter"); std::ofstream ofs("Book.txt"); boost::archive::text_oarchive oa(ofs); oa << &book; ofs.close(); Book* read; // 移除std::ios::binary,用文本模式匹配text_iarchive std::ifstream ifs("Book.txt"); boost::archive::text_iarchive ia(ifs); ia >> read; // 验证反序列化结果 std::cout << "读取到的书名:" << read->get_name() << std::endl; // 释放动态分配的内存 delete read; ifs.close(); }
关键修正点
- 反序列化时移除
std::ios::binary,使用默认文本模式打开文件,匹配text_oarchive的输出格式。 - 删除
serialize方法中的ar & name,避免与save_construct_data的序列化操作重复。 - 添加内存释放代码,防止内存泄漏。
内容的提问来源于stack exchange,提问作者felixkellenbenz
相关产品推荐
相关产品推荐

