在c ++中将向量结构写入二进制文件

时间:2014-01-30 08:40:45

标签: c++ file serialization vector struct

我有一个结构,我想将它写入二进制文件(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?是否有更好/更快或更有效的方式来编写它?

我是否必须序列化数据?

...谢谢

2 个答案:

答案 0 :(得分:6)

std::string投射到char *不会产生您期望的结果。也不会在其上使用sizeofstd::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将花费更多时间来完成写入,因此会消耗几微秒,这将在背景噪声中丢失。

但是,完全不酷。