将内存转储到文件

时间:2010-10-12 09:16:13

标签: c

我有一部分内存要转储到文件中。一个原因是在某处保存信息,另一个原因是在我的程序重新启动时再次读取它。

这样做的正确方法是什么?

我的第一个想法是:

char* start = my_pointer;
int i;
for (i = 0; i < MEMORY_SIZE; i++) {
    // write *start to file
    start++;
}

我可以把它全部写成字符吗?然后使用这样的东西将其恢复到内存中。

//loop
    *my_pointer = fgetc(f);
    my_pointer++;

我的“数据结构”是否会像“charachters”一样存在,还是需要以某种二进制/ hexa数据模式编写?或者这是一种标准的做法吗?

5 个答案:

答案 0 :(得分:9)

这个问题被称为“serializing”,范围从琐碎到真正复杂。如果您的数据结构是自包含的,例如数组中的一堆像素,并且您知道数组维度,则可以将数据转储出来然后将其读回。

如果您的数据中有链接列表或任何类型的指针,那么一旦您将它们读回,这些指针就不会指向任何有效的指针。这是一种更正式的序列化方法开始有意义的地方。

这可以包括保存为文件格式,使用数据库,转换为XML或其他分层格式等。什么是OK解决方案完全取决于您拥有什么类型的数据,以及您正在对其执行的操作类型以及您计划编写然后从磁盘读回的常常。 (或网络。或者无论你在做什么。)

如果您拥有的是一小部分数据,而您只想以最简单的方式编写,请使用fwrite()

fwrite(my_pointer, MEMORY_SIZE, 1, fp);

然后fread()重新读取数据。 另请参阅相关信息(或多或少相关,具体取决于您的需求有多高级)serializing question on StackOverflow

当不同类型的CPU应该能够彼此读取数据时,正确的serialization也会解决the problems that appear。 C语言中的正确序列化比其他语言复杂得多。例如,在Lisp中,所有数据和代码都已经序列化。在Java中,有一些方法可以帮助您序列化数据。 C语言的特性使其成为高性能和系统编程的合适语言,这也使其更难以用于其他一些事情。

答案 1 :(得分:2)

如果您使用的是unixy样式系统memmap,memcpy可能会为您提供整洁的解决方案。

答案 2 :(得分:2)

您可以使用

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

功能

ptr - pointer to you memory segment.
size - size of memory to write.
stream - file you writing to.
  

我的“数据结构”是否会像“charachters”一样存在,还是需要以某种二进制/ hexa数据模式编写?或者这是一种标准的做法吗?

打开文件时 - 在“mode”param中使用“b”字符

答案 3 :(得分:2)

只要您要转出的数据不包含指针,只需将其转出就可以了。 (提示:使用可以一次编写长序列数据的调用来缩短时间。)唯一需要注意的是,如果你要写出整数或浮点数并将它们读回到一台机器上不同的架构(例如,大端而不是小端)。这可能是也可能不是你的担忧。

但如果你有指针,你就有问题了。问题是你不能(好吧,不能轻易)保证你将数据加载回接收进程的虚拟内存空间中的相同位置。更重要的是,如果您的数据指向您未保存的内容(例如,流浪FILE*),那么您必须考虑如何在此时重新合成有效的替换。这样的序列化是非常重要的,并且需要编写具有您正在保存和加载的确切知识的代码。

当你只保存连续数据中的指针并且总是要在同一架构上恢复时,有一种方法可以简化序列化。像往前一样转储内存,但是在其上放一个前缀描述符,至少说明数据的长度和指针的数量,然后还保存(最后)一个确切位置的表(作为数据中的偏移量)指针是所有数据的起点。然后,您可以通过读取数据并执行地址算法来恢复所有指针,即,您可以计算出相对于它们指向的原始数据的开头的偏移量 - 作为char*,而不是{{1}}原始类型 - 并确保它们在重新加载后指向相对于整个数据地址的相同偏移量。这是一个有点严重的黑客攻击,并且在形式上并不是最便携的东西,但在本段开头所述的限制范围内,我希望它能够发挥作用。但是你也会有一个非常便携的序列化格式;对于任何类型的持久存档使用,都不要指望

答案 4 :(得分:1)

这样做的正确方法是使用序列化库。

您是否真的需要这取决于数据的复杂程度。如果您需要写出的数据不包含任何类型的指针,那么您可以使用fwrite将数据写出来并fread将其读回来。只需确保您有用二进制模式打开数据文件。

如果要序列化的数据包含指针,那么使用为此目的编写的外部库会更好,因为库将确保指针的编写方式可以在以后正确地重构。