【发布时间】:2020-09-13 19:48:42
【问题描述】:
我有以下类字段:
int _number;
string _name;
int _amount;
bool _isAvailable;
double _price;
int _storageTime;
int _entranceDay;
int _entranceMonth;
int _entranceYear;
我应该如何序列化/反序列化该类的对象?
我试过这个:
void Serialize() {
ofstream ofs("tmp.bin", ios::binary | ios::out);
ofs.write((char*)& _number, sizeof(int));
ofs.write((char*)& _amount, sizeof(int));
ofs.write((char*)& _isAvailable, sizeof(bool));
ofs.write((char*)& _price, sizeof(double));
ofs.write((char*)& _storageTime, sizeof(int));
ofs.write((char*)& _entranceDay, sizeof(int));
ofs.write((char*)& _entranceMonth, sizeof(int));
ofs.write((char*)& _entranceYear, sizeof(int));
int stringSize = _name.size();
ofs.write((char*)& stringSize, sizeof(int));
for (int i = 0; i < stringSize; ++i) {
char c = _name[i];
ofs.write(&c, sizeof(char));
}
ofs.close();
}
这用于反序列化:
void Deserialize() {
ifstream ifs("tmp.bin", ios::binary | ios::in);
ifs.read((char*)& _number, sizeof(int));
ifs.read((char*)& _amount, sizeof(int));
ifs.read((char*)& _isAvailable, sizeof(bool));
ifs.read((char*)& _price, sizeof(double));
ifs.read((char*)& _storageTime, sizeof(int));
ifs.read((char*)& _entranceDay, sizeof(int));
ifs.read((char*)& _entranceMonth, sizeof(int));
ifs.read((char*)& _entranceYear, sizeof(int));
int stringSize;
ifs.read((char*)& stringSize, sizeof(string));
string name;
for (int i = 0; i < stringSize; ++i) {
char c;
ifs.read(&c, sizeof(char));
name += c;
}
_name = name;
ifs.close();
}
序列化不会抛出任何异常。至于反序列化 - 它会引发异常:“运行时检查失败 #2 - 变量 'ifs' 周围的堆栈已损坏。” 调试器显示,对于字符串字段,所有字段都已正确反序列化。 那么,如何正确序列化/反序列化一个字符串呢?
【问题讨论】:
-
在其他一些说明中,您的序列化是不可移植的。例如的大小
int不是固定的,它的endianness 也不是。double类型也是不可移植的,它的二进制表示不是由 C++ 指定的,它通常取决于硬件。和int一样,bool的大小没有指定。 是指定的是sizeof(char)将始终等于1,无论实际使用的位数如何。 -
字符串的序列化和反序列化代码都可以简化:您知道要写入和读取的元素的长度和数量,因此可以一次性完成所有的写入和读取。对于写作方面,只需做
ofs.write(_name.data(), _name.size());,在阅读大小上,做例如_name.resize(size); ifs.read(_name.data(), _name.size());
标签: c++ string file serialization binary