如何手动实现C++对象到二进制文件的序列化与反序列化(无第三方库)
手动实现C++二进制序列化/反序列化的方案
核心逻辑:所有动态长度类型(
std::string、std::vector等)的序列化都遵循「先写入长度值,再写入对应长度的二进制内容」的规则,固定大小类型(如int)可以直接写入二进制内容,读写时保持顺序一致即可。
具体实现代码
你可以直接在Student类中新增序列化、反序列化的成员方法,封装所有二进制读写逻辑:
#include <fstream> #include <string> #include <vector> class Student{ std::string name, email, telephoneNo; int addmissionNo; std::vector<std::string> issued_books; public: // 原有构造、字段初始化等方法保留 // 序列化:将当前对象写入二进制输出流 void serialize(std::ofstream& out) const { // 1. 写入固定大小的int字段 out.write(reinterpret_cast<const char*>(&addmissionNo), sizeof(addmissionNo)); // 2. 写入所有string类型字段 serialize_string(out, name); serialize_string(out, email); serialize_string(out, telephoneNo); // 3. 写入vector<string>字段:先存vector长度,再逐个序列化内部字符串 size_t book_count = issued_books.size(); out.write(reinterpret_cast<const char*>(&book_count), sizeof(book_count)); for (const auto& book : issued_books) { serialize_string(out, book); } } // 反序列化:从二进制输入流读取内容填充当前对象 void deserialize(std::ifstream& in) { // 1. 读取固定大小的int字段 in.read(reinterpret_cast<char*>(&addmissionNo), sizeof(addmissionNo)); // 2. 读取所有string类型字段 deserialize_string(in, name); deserialize_string(in, email); deserialize_string(in, telephoneNo); // 3. 读取vector<string>字段 size_t book_count; in.read(reinterpret_cast<char*>(&book_count), sizeof(book_count)); issued_books.resize(book_count); for (size_t i = 0; i < book_count; ++i) { deserialize_string(in, issued_books[i]); } } private: // 封装string的通用序列化逻辑 void serialize_string(std::ofstream& out, const std::string& str) const { size_t len = str.size(); // 先写字符串长度 out.write(reinterpret_cast<const char*>(&len), sizeof(len)); // 再写字符串实际内容 out.write(str.data(), len); } // 封装string的通用反序列化逻辑 void deserialize_string(std::ifstream& in, std::string& str) { size_t len; // 先读字符串长度 in.read(reinterpret_cast<char*>(&len), sizeof(len)); str.resize(len); // 再读对应长度的内容 in.read(str.data(), len); } };
使用示例
int main() { // 序列化写入文件 Student s1; // 此处省略s1各个字段的赋值逻辑 std::ofstream out_file("student.dat", std::ios::binary); s1.serialize(out_file); out_file.close(); // 反序列化读取文件 Student s2; std::ifstream in_file("student.dat", std::ios::binary); s2.deserialize(in_file); in_file.close(); return 0; }
注意事项
- 读写文件必须指定
std::ios::binary标志,否则Windows平台会自动转义换行符,导致二进制内容错乱。 - 如果需要先将对象序列化到内存缓冲区再批量写入文件,只需要将
serialize/deserialize方法的参数替换为std::stringstream,同时指定std::ios::binary打开模式即可,内部读写逻辑不需要修改。 - 上述实现默认读写在同一架构、同一编译器的设备上运行,如果需要跨平台兼容,需要额外处理大小端、类型长度差异问题(比如固定用
int32_t存储长度,序列化前统一转成大端/小端字节序,反序列化后转成本地字节序)。 - 如果类包含指针类型成员,不能直接写入指针地址,需要按照动态类型的处理思路,序列化指针指向的实际内容。
内容的提问来源于stack exchange,提问作者Ethan Rodrigo
相关产品推荐
相关产品推荐

