繁体   English   中英

C++:当数据复杂时读/写二进制数据到文件

[英]C++ : Read/Write Binary data to file when data is complex

如果我还必须定义如何保存我的数据,我将如何将数据写入/读取到二进制文件?
我试图将一些简单的数据结构保存到二进制文件中。

例如,我有一个像这样的结构向量:

struct Vertex
{
    x;
    y;
    z;
}

std::vector<Vertex> vertices;

我想将此向量保存到二进制文件中。

我知道如何使用ifstreamostream使用<<>>运算符输出它,这些运算符可以重载以处理我的数据,但它们不能输出二进制。

我也知道如何使用 .write() 以二进制形式写入,但问题是我找不到一种方法来重载我需要的内容,以处理我的数据。

这是对类似问题的回答 虽然这在您的情况下没问题,但请注意,如果您在结构中使用指针,这将不起作用。

指针的意思是:“在另一个内存段中加载了相关数据”,但实际上,它只包含内存的地址。 然后写操作会保存这个内存位置。 当您将其加载回来时,内存中保留您想要的信息的可能性很小。

人们通常做的是创建一个序列化机制。 将一个方法添加到您的结构中,或者编写另一个函数,将您的结构作为参数并以您决定的特殊格式输出包含数据的 char* 数组。 您还需要相反的函数来读取文件并从二进制数据重新创建结构。 你应该看看boost::serialization ,它处理这个非常常见的编程问题。

一种方法(不一定是最好的)是写入数据,使用您选择的任何二进制写入函数,例如

write(fd,data,size);

但是将“数据”作为结构传递。

例如

Vertex data;
data.x = 0;
etc...
write(fd,(char*)&data,sizeof(data));

这会将结构视为字符数组,然后将它们写入文件。 读回应该是上面的相反。

请注意,使用向量(它们是动态分配的并且我在内存中的奇怪位置有奇怪的东西)并没有真正的好方法,因此我建议使用结构数组。

我一直在寻找一种有效且紧凑的方式来永久存储数据,但找不到任何可执行的最小示例,因此我为您整理了它。

该解决方案的美妙之处在于能够随心所欲地处理“向量”中的数据并随心所欲地扩展“结构”(只需稍作更改)

这样,在内存中表示的“向量”被传输到驱动器,然后再通过“std::vector”提供的“data()”方法返回。

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#define FILENAME "data.bin"

struct Vertex
{
    size_t x{};
    size_t y{};
    std::string z{};
};

void writeVectorToBinary(std::vector<Vertex> &v);
void readVectorFromBinary(std::vector<Vertex> &v);
void printVector(std::vector<Vertex> &v);

int main()
{
std::vector<Vertex> vertices;
vertices.push_back({1,2,"three"});
vertices.push_back({4,5,"six"});

writeVectorToBinary(vertices);
printVector(vertices);
readVectorFromBinary(vertices);
printVector(vertices);

std::cin.get();
return 0;
}


void writeVectorToBinary(std::vector<Vertex> &v)
{
  size_t size = v.size();
  //Open Binary file, to write out data
  std::ofstream file(FILENAME, std::ios::binary);
  if(!file)
    std::cout << "Something went wrong" << std::endl;
  //Store/Write the vector size
  file.write(reinterpret_cast<const char*>(&size), sizeof(size));
  //Store/Write the data of the vector out
  file.write(reinterpret_cast<const char*>(v.data()), sizeof(v[0])*size);
  //Close binary file
  file.close();
}

void readVectorFromBinary(std::vector<Vertex> &v)
{
//Clear Vector just for the proof of concept
v.clear();
size_t size{};
//Open Binary file to read in data
std::ifstream file(FILENAME,std::ios::binary);
if(!file)
  std::cout << "Something went wrong" << std::endl;
//Read the vector size
file.read(reinterpret_cast<char*>(&size), sizeof(size));
//Resize vector now that its known
v.resize(size);
//Read vector data in
file.read(reinterpret_cast<char*>(v.data()), sizeof(v[0])*size);
//Close binary file
file.close();
}

void printVector(std::vector<Vertex> &v)
{
  for(size_t i{}; i < v.size(); ++i ){
    std::cout << "\n------Vector" << i << "--------" << std::endl;
    std::cout << v[i].x << std::endl;
    std::cout << v[i].y << std::endl;
    std::cout << v[i].z << std::endl;
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM