在没有序列化库的情况下,在c ++中从一个文件读取和写入数据的最简单方法是什么?

Dav*_*rek 5 c++ fstream

我正在编写一个程序,定期存储并读取下面表格中的结构.

struct Node {
    int leftChild = 0;
    int rightChild = 0;
    std::string value;
    int count = 1;
    int balanceFactor = 0;
};
Run Code Online (Sandbox Code Playgroud)

我如何读取和写入文件的节点?我想使用带有seekg和seekp的fstream类来手动进行序列化,但我不确定它是如何根据文档工作的,并且我正在努力寻找合适的例子.

[edit]指定我不想使用序列化库.

Cla*_*dio 5

此问题称为序列化.使用序列化库,例如Google的Protocol BuffersFlatbuffers.


Tho*_*ews 3

要序列化对象,您需要坚持以下概念:对象将其成员写入流并从流中读取成员。此外,成员对象应该将自己写入流(以及读取)。

我使用三个成员函数和一个缓冲区实现了一个方案:

void load_from_buffer(uint8_t * & buffer_pointer);  
void store_to_buffer(uint8_t * & buffer_pointer) const;  
unsigned int size_on_stream() const;  
Run Code Online (Sandbox Code Playgroud)

首先会size_on_stream调用 来确定对象的缓冲区大小(或者它在缓冲区中占用了多少空间)。

load_from_buffer函数使用给定的指针从缓冲区加载对象的成员。该函数还适当地增加指针。

store_to_buffer函数使用给定的指针将对象的成员存储到缓冲区。该函数还适当地增加指针。

这可以通过使用模板和模板专业化应用于 POD 类型。

这些函数还允许您将输出打包到缓冲区中,并从打包格式加载。

I/O 到缓冲区的原因是这样您可以使用更高效的流方法,例如writeread

编辑1:将节点写入流
写入或序列化节点(例如链表或树节点)的问题是指针不会转换为文件。无法保证操作系统每次都会将您的程序放置在相同的内存位置或为您提供相同的内存区域。

您有两个选择:1)仅存储数据。2) 将指针转换为文件偏移量。选项 2) 非常复杂,因为它可能需要重新定位文件指针,因为文件偏移量可能无法提前知道。

另外,请注意可变长度记录,例如字符串。您不能直接将字符串对象写入文件。除非您使用固定的字符串宽度,否则字符串大小将会改变。您需要在字符串前添加字符串长度(首选)或使用某种终止字符,例如“\0”。优先考虑字符串长度,因为您不必搜索字符串的末尾;您可以使用块读取来读取文本。