C – 将指针数据保存/加载到文件

如果之前已经提出这个问题,或者有一个我看不到的明显的解决方案,首先道歉.我找到了一个
similar的问题,但我相信我所要求的比前面提到的更进一步.

我的结构如下:

typedef struct {
        int id;
        char *title;
        char *body;
} journal_entry;

问:如何在不使用固定长度的情况下在C(而不是C)中编写和加载指向内存的指针内容?

我错误地认为通过将标题或正文写入文件我会最终得到垃圾数据而不是实际存储的信息?我不知道日记帐分录的标题或正文的大小,并且从入口到入口的大小可能会有很大差异.

我自己的阅读建议我需要取消引用指针并分别对结构的每个部分进行构造.但我不确定如何跟踪数据和结构,而不会让事情变得混乱,特别是对于较大的文件.此外,如果这些不是我打算存储在文件中的唯一项目(例如我可能希望稍后包含小图像,我不确定如何为了方便而订购文件结构.

另一个(可能是感知的)问题是我在加载数据时使用malloc为主体/条目的字符串分配内存当我希望再次加载条目时,如何知道为字符串分配多少内存?我是否需要扩展我的结构以包含int body_len和int title_len?

非常感激地收到指导或建议.

最佳答案 (我专注于Linux的观点,但它可以适应其他系统)

序列化

你想要实现的通常被称为serialization(引用维基百科) – 或编组:

The serialization is the process of translating data structures or object state into a format that can be stored and reconstructed later in the same or another computer

指针I / O.

原则上可以读写指针,例如fprintf(3)&的%p转换规范fscanf(3)(您可能直接写和读指针,这就好比是机器级的一些使用intptr_t整数.不过,具体的地址(例如0x1234F580 …)很可能是无效的或由再次读取时,可以有不同的含义不同的过程(例如因为ASLR).

汇总数据的序列化

您可以使用像JSON某些文本格式(实际上我建议这样做)或其它格式类似YAML(或者发明你自己的,例如,通过s-exprs的启发).优先考虑文本格式(并且自1980年以来Unix有这种习惯)到二元文本格式(如XDR,ASN/1,…).许多协议(HTTP,SMTP,FTP,JSONRPC ……)都是文本协议

请注意,在当前系统中,I / O比计算慢得多,因此文本编码的相对成本和解码很小w.r.t.网络或磁盘IO(参见答案here表)

一个一些聚合数据(在C例如一个结构)的编码一般是组合的,和通过合成基本标量数据的编码(数字,字符串,…),则可以进行编码一些更高级别的数据类型.

序列化库

大多数格式(尤其是JSON)具有若干自由软件库以对它们进行编码/解码,例如, Jansson,JsonCPP

建议:

使用JSON并将您的journal_entry格式化为类似的JSON对象

{ "id": 1234,
  "title": "Some Title Here",
  "body": "Some body string goes here" }

具体来说,您将使用一些JSON库并首先将您的journal_entry转换为某种JSON类型(反之亦然),然后使用该库对JSON进行编码/解码

数据库

您还可以考虑采用数据库方法(例如sqlite等)

PS.闭包的序列化(或包含指向代码的指针的任何内容)可能具有挑战性.您需要确定具体含义.

PPS.某些语言提供内置的序列化和编组支持.例如,Ocaml有一个Marshal模块,Python有pickle

点赞