我们过去有一个结构:
const int NUMBER_OF_ELEMENTS = 10;
struct myStruct1
{
uint32_t var1;
uint64_t var2;
uint32_t elements[NUMBER_OF_ELEMENTS];
};
然而,今后我们希望元素的数量是可变的。我想我最好这样做:
struct myStruct2
{
uint32_t var1;
uint64_t var2;
std::vector<uint32_t> elements;
myStruct2(int len){ elements.resize(len);};
};
对于从文件中读取/写入,我们过去只需执行以下操作:
myStruct1 ms1;
std::ofstream outfile(FILENAME,std::ofstream::out | std::ofstream::binary);
outfile.write((const char*)&ms1,sizeof(myStruct1));
outfile.close();
myStruct1 msread1;
std::ifstream infile(FILENAME, std::ifstream::in | std::ifstream::binary);
infile.read((char *)&msread1, sizeof(myStruct1));
infile.close();
显然,对于矢量版本,我不能再这样做了。所以,我必须逐个元素地阅读。
myStruct2 msread2(NUMBER_OF_ELEMENTS);
std::ifstream infile(FILENAME, std::ifstream::in | std::ifstream::binary);
infile.read((char *)&msread2.var1, sizeof(uint32_t));
infile.read((char *)&msread2.var2, sizeof(uint64_t));
for (int i=0; i<NUMBER_OF_ELEMENTS; i++)
{
infile.read((char *)&msread2.elements[i], sizeof(uint32_t));
}
infile.close();
然而,这会遇到字节对齐的问题。。。在结构(和文件(中的var1之后有4个字节的填充。读var1然后读var2不会跳过这个pad。
我可以使用#pragma pack(1(进行写作和阅读。然而,我希望阅读器与使用填充创建的旧文件兼容。
在读取var1之后,我可以手动查找4个字节(或者读取一个伪4字节变量(。但我觉得可能还有更好的方法。
我可以将var1和var2放在myStruct1或myStruct2中它们自己的结构中,然后一起读取它们,也许这对io来说更干净一些,但访问它们将需要额外的步骤,例如ms1.headvars.var1,而不仅仅是ms1.var1。(整个代码库中有更多变化(
有什么更好的解决方案的建议吗?
不能简单地将矢量二进制文件写入磁盘;它在内部包含所使用的大小和指向动态分配的真实数据的指针(以及编译器制造商喜欢放在那里的任何其他东西;以任何顺序(。您最多可以将指针值写入文件中。
相反,您需要编写大小,然后分两个步骤编写内容:v.size()
和v.data()
读回时,您首先读取大小,准备一个向量,然后读回数据:v.resize(size);
,然后读入v.data()
[是的,您可以写入v.data()
!]