我有一个结构,我想将它写入二进制文件(c ++ / visual studio 2008)。 结构是:
struct DataItem
{
std::string tag;
std::vector<int> data_block;
DataItem(): data_block(1024 * 1024){}
};
我用随机值填充data_block向量:
DataItem createSampleData ()
{
DataItem data;
std::srand(std::time(NULL));
std::generate(data.data_block.begin(), data.data_block.end(), std::rand);
data.tag = "test";
return data;
}
尝试将结构写入文件:
void writeData (DataItem data, long fileName)
{
ostringstream ss;
ss << fileName;
string s(ss.str());
s += ".bin";
char szPathedFileName[MAX_PATH] = {0};
strcat(szPathedFileName,ROOT_DIR);
strcat(szPathedFileName,s.c_str());
ofstream f(szPathedFileName, ios::out | ios::binary | ios::app);
// ******* first I tried to write this way then one by one
//f.write(reinterpret_cast<char *>(&data), sizeof(data));
// *******************************************************
f.write(reinterpret_cast<const char *>(&data.tag), sizeof(data.tag));
f.write(reinterpret_cast<const char *>(&data.data_block), sizeof(data.data_block));
f.close();
}
主要是:
int main()
{
DataItem data = createSampleData();
for (int i=0; i<5; i++) {
writeData(data,i);
}
}
所以我希望文件大小至少为(1024 * 1024)* 4(对于矢量)+ 48(对于标记),但它只是将标记写入文件并创建1KB文件到硬盘。
我在调试时可以看到内容,但是没有将其写入文件......
这段代码有什么问题,为什么我不能将strcut写入vector to file?是否有更好/更快或更有效的方式来编写它?
我是否必须序列化数据?
...谢谢
答案 0 :(得分:6)
将std::string
投射到char *
不会产生您期望的结果。也不会在其上使用sizeof
。 std::vector
。
对于矢量,您需要使用std::vector::data
方法,或使用例如&data.data_block[0]
。至于尺寸,请使用data.data_block.size() * sizeof(int)
。
写字符串是另一回事,特别是如果它可以是可变长度的话。您必须将其写为固定长度的字符串,或者写入长度(以固定大小的格式),然后是实际的字符串,或者在字符串的末尾写一个终结符。要获得指向字符串的C样式指针,请使用std::string::c_str
。
答案 1 :(得分:1)
欢迎来到C ++ std ::
的欢乐世界基本上,矢量用作不透明的容器
您可以立即忘记reinterpret_cast
尝试关闭编译器将允许您创建可执行文件,但它会产生愚蠢的结果。
基本上,你可以忘记大部分与迭代器有关的std :: vector语法糖,因为你的fstream不会通过它们访问二进制数据(它会输出你数据的文本表示)。
但一切都没有丢失。
您可以使用新的(C ++ 11)引入的.data()方法访问矢量基础数组,但这会使得使用opaque类型失败。
const int * raw_ptr = data.data_block.data();
这将获得100分的酷因子,而不是使用微不足道的
const int * raw_ptr = &data.data_block.data[0];
您还可以使用更加神秘的&data.data_block.front()
获得50分的酷炫因子奖励。
然后你可以一次性写出你的整体:
f.write (raw_ptr, sizeof (raw_ptr[0])*data.data_block.size());
现在,如果你想做一些非常简单的事情,试试这个:
for (int i = 0 ; i != data.data_block.size() ; i++)
f.write (&data.data_block[i], sizeof (data.data_block[i]));
由于磁盘I / O将花费更多时间来完成写入,因此会消耗几微秒,这将在背景噪声中丢失。
但是,完全不酷。