我正在尝试使用 boost 序列化库来序列化一个类。序列化工作得很好,但是当我尝试读取写入文件的内容时,出现“输入错误”异常。
我阅读了 boost 序列化库的文档并提出了 (1) 了解如何使用非默认构造函数序列化和反序列化类。我试图尽可能接近文档中的示例。
我尝试从 Book 类的序列化方法(文档示例中所做的)中删除 ar & name
,这也导致了输入流错误。
调试时,我发现在 load_primitive` 函数的 load _access
类中引发了异常。
源代码(1)
#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
提前感谢任何遮阳篷。 菲利克斯
最佳答案
save_construct_data()
和 load_construct_data()
应该一起工作,但在您的代码中,save_construct_data()
永远不会被调用。发生这种情况是因为它的签名不正确:Book*
应该是 const Book*
。
然后,您会收到流错误,因为序列化和反序列化彼此不一致 - 序列化在 serialize()
中写入一次 Book::name
,但反序列化会尝试在 load_construct_data()
和 serialize()
中读取两次。
完整的工作示例(main()
未更改,除了删除 std::ios::binary
):
class Book {
friend class boost::serialization::access;
private:
std::string name;
template<class Archive>
void serialize(Archive&, unsigned int) { }
template<class Archive>
friend void save_construct_data(Archive& ar, const Book* book, unsigned int) {
ar << book->name;
}
template<class Archive>
friend void load_construct_data(Archive& ar, Book* book, unsigned int) {
std::string name;
ar >> name;
::new(book) Book(std::move(name));
}
public:
Book(std::string name): name(std::move(name)) { }
};
我在类中将 save_construct_data()
声明为 friend
以简化代码。由于某种原因,如果它是在 boost::serialization
命名空间中定义的,除了与 boost::serialization 建立友好关系之外,您还需要为该函数添加一个
。文档中没有提到这一点,但如果没有 friend
声明::访问friend
声明,代码将无法编译。
关于c++ - 使用 boost 反序列化时输入流错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76889919/