文件系统中的数据结构存储

Datastructure Storage in Filesystem

本文关键字:存储 数据结构 文件系统      更新时间:2023-10-16

我正在尝试用C++编写一个持久的数据结构,但是我觉得我应该能够使其与我的数据结构读取器的各种其他实现二进制兼容,因此,我目前的想法是在没有任何抽象的情况下在本机内存中声明数据结构。

例如,我会指定一个线性内存块作为数据结构(使用 new 关键字(,然后描述第一个字节的含义,第二个字节的含义等等。我知道我可以使用struct来做到这一点,但是,数据结构将绑定到一种语言,而其他语言将不得不使用此结构。此外,实现可能会从编译器更改为编译器。相反,我希望它作为内存标准。

我试图做的事情有点合理吗?或者我试图过度简化事情,真的应该继续使用struct数据结构?现在进入C++部分,如果您认为我应该使用struct数据结构,那么使用成熟的类有什么缺点?

(无论如何,

我正在使用一个类来包装内存结构并为其提供函数,因为数据结构无论如何都是持久的。编辑正如 justin 所建议的那样,我不需要任何围绕内存结构的高级接口包装器,所以我关于类包装器的最后一点没有正确说明。我的意思是,我希望有一个用于内存表示的类接口,它不一定是包装器。

我读过/使用的几种文件格式正是这样做的——定义内存标准或布局,然后通常用类似 C 的伪struct ure 演示来支持它。有时它们会提供结构或类表示,有些则完全由库抽象。当然,这些格式继续记录所有字段、它们的大小、数据的字节序等。

我认为与字节序相关的问题、填充、复杂性(例如,由数据结构的变化引入(和正确的版本控制是错误的最大来源。我发现的另一个问题是使用过去的数据结构以及用于表示类似功能的数据结构的不一致 - 您可能会收到一个规范,并意识到它包含几种不同的字符串表示形式 - 所有这些都是过时的,必须有人继续支持所有这些(双向(。

继续该路线:

如果您不想支持二进制表示(或可编译程序(,则不应提交它(随着平台和工具集的变化,长期格式的尝试会失败/绊倒(。只需首先提交正式的内存标准,然后在此基础上构建测试和示例输入文件,以验证表示是否正确序列化和反序列化。一个非常基本的测试套件将有助于确保您的模型在您需要的所有系统上都是可移植的,并且可以指出您可能没有意识到的潜在陷阱或平台特定的注意事项。

如果你真的想提供一个可编译的表示,我会坚持一个非常兼容的struct表示——客户端可以采用这个(在内存中(表示并将其转换为他们喜欢的任何C++抽象/表示。也就是说,序列化表示可能不应该反映内存中表示的表示,除了简单的表示和这种表示的中间存储(扁平和打包结构(。

其中一个重要的部分是,你应该进行测试,确认你使用这些结构创建的内存对象图是向前和向后可序列化和反序列化的,并支持正确的版本控制 - 因此通常需要一些工作才能使复杂的序列化表示兼容。所以你看到这种方法只是在另一个抽象层之上引入了一个抽象层。在这方面,您可能希望为C++抽象提供从打包内存表示形式创建自身的能力,并确保该表示形式也可以正确填充打包结构而不会丢失数据。

除此之外,是否需要更高级的界面?如果有,那么您可能需要提供该信息。

所以,是

的,内存标准是你必须获得正确和稳定的部分,并且所有实现都应该参考和测试它 - 无论平台/架构差异如何。IOW,你走在正确的轨道上;)

在C++中,structclass 之间没有实际区别(除了默认的可访问性在 struct 中是公共的(。传统上,当类型只有(公共(成员变量而没有成员函数时,使用 struct,但这只是一个约定,而不是编译器强制执行的规则。

我肯定会使用struct/class来描述数据。如果有人想编写数据结构的读取器,他们可以导入您的头文件或用他们选择的语言实现数据结构 - 在大多数编程语言中,这应该非常简单。

我建议你像这样开始你的结构:

typedef struct
{
    int Version; // struct layout version
    int ByteSize; // byte size of structure for validation
    ...
} MYDATA;

这样,当传递数据结构时,代码可以验证分配的结构大小是否与给定版本的结构的预期字节数匹配。然后,您只需更新版本字段并检查新大小,即可轻松引入结构的新版本。

将数据保存到磁盘时,请确保逐个字段地写出数据,而不是通过单次写入(使用指针和sizeof(),以确保其他语言不必处理C++编译器可能决定放入的潜在填充。可以在结构中手动布局字段,以便没有填充,但是在执行此操作时必须非常非常小心,并且很容易出错。