将矢量的结构写入C 中的二进制文件

Writing struct of vector to a binary file in c++

本文关键字:二进制文件 结构      更新时间:2023-10-16

我有一个结构,我想将其写入二进制文件(C /Visual Studio 2008)。结构是:

struct DataItem
{
  std::string tag;        
  std::vector<int> data_block;
  DataItem(): data_block(1024 * 1024){}
};

我用随机值填充tha data_block vector:

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(for vector) 48(用于标签),但它只是将标签写入文件并将1KB文件创建到硬盘驱动器。

我可以在调试时看到其中的内容,但不会将其写入文件...

此代码有什么问题,为什么我不能将strcut写入向量归档?是否有更好/更快或可能有效地编写它的方法?

我必须序列化数据吗?

谢谢...

std::string投射到char *不会产生您期望的结果。在上面使用sizeof也不会。std::vector也是如此。

对于向量,您需要使用std::vector::data方法或使用例如。&data.data_block[0]。至于大小,请使用data.data_block.size() * sizeof(int)

编写字符串是另一回事,尤其是如果它的长度可变。您要么必须将其写入固定长度字符串,要么以实际的字符串写入长度(以固定尺寸的格式),或者在字符串末端编写终结器。要获取c风格的指针到字符串,请使用std::string::c_str

欢迎来到C STD的快乐世界::

基本上,向量被用作不透明的容器。
您可以立即忘记reinterpret_cast
尝试关闭编译器将允许您创建一个可执行文件,但会产生愚蠢的结果。

基本上,您可能会忘记与迭代器有关的大多数std :: vector句法糖,因为您的fstream将无法通过它们访问二进制数据(它将输出您的数据的文本表示)。

,但一切都没有丢失。

您可以使用新的(C 11)引入.DATA()方法访问矢量基础数组,尽管这打败了使用不透明类型的点。

const int * raw_ptr = data.data_block.data();

将获得100点酷因子,而不是使用微弱

const int * raw_ptr = &data.data_block.data[0];

您也可以将更多的密码&data.data_block.front()用于50分的酷因子奖金。

然后,您可以一口气写下ints的地球:

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将需要更多时间完成写入。

完全不酷。