C-将指针数据保存/加载到文件 [英] C - Save/Load Pointer Data to File

查看:352
本文介绍了C-将指针数据保存/加载到文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先道歉,如果这个问题之前曾有人提出过,或者有我看不到的明显解决方案.我发现了一个类似问题,但是我相信我要问的问题有点比以前的要求更进一步.

Firstly apologies if this question has been asked before or has a glaring obvious solution that I cannot see. I have found a similar question however I believe what I am asking goes a little further than what was previously asked.

我的结构如下:

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

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

我是否错误地认为,通过将titlebody写入文件,我最终会得到垃圾数据,而不是实际上存储的信息吗?我不知道日记帐分录的titlebody的大小,并且该大小可能因条目而异.

Am I wrong in thinking that by writing title or body to file I would endup with junk data and not actually the information I had stored? I do not know the size that the title or body of a journal entry would be and the size may vary significantly from entry to entry.

我自己的阅读建议我将需要分别取消引用指针和fwrite结构的每个部分.但是我不确定如何跟踪数据和结构,而不会引起混乱,尤其是对于较大的文件.此外,如果这些不是我打算存储在文件中的唯一项(例如,我可能希望稍后再包含小图像,那么我不确定如何为方便起见而对文件结构进行排序.

My own reading suggests that I will need to dereference pointers and fwrite each part of the struct separately. But I'm uncertain how to keep track of the data and the structs without things becoming confused particularly for larger files. Furthermore if these are not the only items I intend to store in the file (for example I may wish to include small images later on I'm uncertain how I would order the file structure for convenience.

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

The other (possibly perceived) problem is that I have used malloc to allocate memory for the string for the body / entry when loading the data how will I know how much memory to allocate for the string when I wish to load the entry again? Do I need to expand my struct to include int body_len and int title_len?

我们将非常感谢您的指导或建议.

Guidance or suggestions would be very gratefully received.

推荐答案

(我主要关注Linux的观点,但它可能适用于其他系统)

您想要实现的目标通常称为序列化(引用维基百科)-或编组:

What you want to achieve is often called serialization (citing wikipedia) - or marshalling:

序列化是将数据结构或对象状态转换为可以在以后在同一台或另一台计算机中存储和重建的格式的过程

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)(您可能直接writeread指针,类似于机器级别的某个intptr_t整数,但是给定的地址(例如0x1234F580 ...)在通过不同的过程再次读取时可能无效或具有不同的含义(例如,由于 ASLR ).

Pointer I/O

It is in principle possible to read and write pointers, e.g. the %p conversion specification for fprintf(3) & fscanf(3) (and you might directly write and read a pointer, which is like at the machine level some intptr_t integer. However, a given address (e.g. 0x1234F580 ...) is likely to be invalid or have a different meaning when read again by a different process (e.g. because of ASLR).

您可以使用某些文本格式,例如 JSON (我实际上建议这样做)或其他格式,例如 YAML (或者也许是发明自己的,例如受 XDR ASN/1 ,...).而且许多协议(HTTP,SMTP,FTP, JSONRPC ....)都是文本协议

You might use some textual format like JSON (and I actually recommend doing so) or other format like YAML (or perhaps invent your own, e.g. inspired by s-exprs). It is a well established habit to prefer textual format (and Unix had that habit since before 1980) to binary ones (like XDR, ASN/1, ...). And many protocols (HTTP, SMTP, FTP, JSONRPC ....) are textual protocols

请注意,在当前系统上,I/O比计算要慢得多,因此文本编码和测试的相对成本较高.解码很小网络或磁盘IO(请参见答案的表此处)

Notice that on current systems, I/O is much slower than computation, so the relative cost of textual encoding & decoding is tiny w.r.t. network or disk IO (see table of Answers here)

一些聚合数据(例如C中的struct)的编码通常是组合的,并且通过组成基本标量数据(数字,字符串等)的编码,您可以对一些更高级别的数据进行编码类型.

The encoding of a some aggregate data (e.g. a struct in C) is generally compositional, and by composing the encoding of elementary scalar data (numbers, strings, ....) you can encode some higher-level data type.

大多数格式(尤其是JSON)都有几个免费的软件库来对它们进行编码/解码,例如詹森

Most formats (notably JSON) have several free software libraries to encode/decode them, e.g. Jansson, JsonCPP, etc..

使用JSON并将您的journal_entry格式化为JSON对象,例如

Use JSON and format your journal_entry perhaps into a JSON object like

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

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

Concretely, you'll use some JSON library and first convert your journal_entry into some JSON type (and vice versa), then use the library to encode/decode that JSON

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

You could also consider a database approach (e.g. sqlite, etc...)

PS.闭包(或包含代码指针的任何东西)的序列化可能是有挑战性的.您需要定义确切的含义.

PS. Serialization of closures (or anything containing pointer to code) may be challenging. You'll need to define what exactly that means.

PPS.某些语言提供了对序列化和编组的内置支持.例如,Ocaml具有 Marshal 模块,Python具有挑剔

PPS. Some languages provide builtin support for serialization and marshalling. For example, Ocaml has a Marshal module, Python has pickle

这篇关于C-将指针数据保存/加载到文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆