最近遇到一个C++读取二进制结构体数据的问题,希望能得到大佬指点,背景是这样的,有一个程序需要保存很多参数,这些参数都存放在一个比较复杂的结构体中,保存和读取都是直接通过fstream中的write和read实现的,现在问题是这个结构体随着软件升级会发生一些改变(比如添加几个参数之类),改变后的结构体就无法解析之前保存的数据了,我想请教一下,有没有一种方法能做到升级后的结构体仍可以解析以前保存的数据呢?二进制分析这种技术有可能解决问题吗?
下面是二进制保存结构体的例子,摘自http://c.biancheng.net/view/302.html。
保存CStudent结构体:
[C++] 纯文本查看 复制代码 #include <iostream>
#include <fstream>
using namespace std;
class CStudent
{
public:
char szName[20];
int age;
};
int main()
{
CStudent s;
ofstream outFile("students.dat", ios::out | ios::binary);
while (cin >> s.szName >> s.age)
outFile.write((char*)&s, sizeof(s));
outFile.close();
return 0;
}
读取CStudent结构体:
[C++] 纯文本查看 复制代码 #include <iostream>
#include <fstream>
using namespace std;
class CStudent
{
public:
char szName[20];
int age;
};
int main()
{
CStudent s;
ifstream inFile("students.dat",ios::in|ios::binary); //二进制读方式打开
if(!inFile) {
cout << "error" <<endl;
return 0;
}
while(inFile.read((char *)&s, sizeof(s))) { //一直读到文件结束
int readedBytes = inFile.gcount(); //看刚才读了多少字节
cout << s.szName << " " << s.age << endl;
}
inFile.close();
return 0;
}
现在的问题相当于CStudent这个结构体变了,如何在读取的时候 inFile.read((char *)&s, sizeof(s)) 仍然可以把以前的数据解析到 (char *)&s 中呢? 我自己想了一种办法就是使用命名空间,将以前的CStudent结构体定义在OldClass命名空间之下,读取的时候判断是不是用OldClass命名空间中的结构体读取解析数据,然后再利用memcpy拷贝到新的结构体中,但是这样做需要每次变动结构体后都需要专门针对结构体的转化写很多东西,有没有更方便更优雅的方式实现这个需求呢? |