假设我们有一个int数组的结构体,一个浮点数组等等,我们需要将它们写入二进制格式文件以便快速重新加载。这可以用简单的方法完成吗?以多平台的方式将4个数组写入文件的最简单方法是什么?
对于每个数组,文件应该是几个?
假设我们有一个int数组的结构体,一个浮点数组等等,我们需要将它们写入二进制格式文件以便快速重新加载。这可以用简单的方法完成吗?以多平台的方式将4个数组写入文件的最简单方法是什么?
对于每个数组,文件应该是几个?
除非您有大量数据,否则只需编写标准文本格式即可。如果您可以假定两端都是c99,则使用格式化程序%a
来获得浮点数据,以避免二进制十进制转换的变幻莫测。
如果数据量很大,或者出于其他原因需要使用“原始数据”格式,则在写入之前,您需要将数据转换为已知的字节序列,并在读取之后将其转换回主机字典序。任何合理理智的操作系统都有用于完成这些转换的库例程。
写在纯文本...然后压缩它
的Presto!二进制格式
添加一些指向C API的链接(stdio,gzip等),使用标准库和跨平台库的额外要点。 – 2010-09-21 16:07:38
我在C中有点生疏,但可能有人已经编写了支持将数组序列化为专门用于写入和/或从文件读取的二进制数据。 Google针对您的特定语言的序列化,可能有人已经为您解决了这个问题。
但是,Endianness可能是一个问题,如果您使用一些奇怪的平台。你也应该使用在所有平台上都有固定大小的类型。
如果您只是寻找一个例子,下面是一个非常简单的例子,绝对没有错误检查。它将具有一些整数的结构的内容写入一个文件,然后再读出它们。然而,其他人关于字节顺序的观点是非常密切的,如果文件要在不同的平台上使用,则需要解决。
typedef struct {
int count;
int *values;
} SomeInts;
int main(int argc, char* argv[])
{
SomeInts ints;
int i;
FILE *fh;
ints.count = 5;
ints.values = (int*)malloc(ints.count * sizeof(int));
for (i = 0; i < ints.count; i++)
ints.values[i] = i * 42;
// write it
fh = fopen(argv[1], "wb");
// really should check amount written to verify it worked
fwrite(&ints.count, sizeof(ints.count), 1, fh);
fwrite(ints.values, sizeof(ints.values[0]), ints.count, fh);
fclose(fh);
// read them back in.
free(ints.values);
memset(&ints, 0, sizeof(ints));
fh = fopen(argv[1], "rb");
// read how many ints (should also check for errors)
fread(&ints.count, sizeof(ints.count), 1, fh);
ints.values = (int*)malloc(ints.count * sizeof(int));
fread(ints.values, sizeof(ints.values[0]), ints.count, fh);
fclose(fh);
for (i = 0; i < ints.count; i++)
printf("%d\n", ints.values[i]);
free(ints.values);
}
如果使用pragma pack(1),则可以在一块内存中执行一次读/写操作。
#include <stdio.h>
#include <memory.h>
typedef struct ca_tag{
int i[4];
float f[3];
}ca_type;
#pragma pack(1)
void init(ca_type* c) // fill it with something
{
c->i[0] = 1; c->i[1] = 2; c->i[2] = 3; c->i[3] = 12;
c->f[0] = 2.3; c->f[1] = 32.3; c->f[2] = 42.3;
}
int main()
{
FILE *stream;
ca_type ca;
char *ptr = (char*)&ca;
char *ptr2 = (char*)&ca;
init(&ca);
if((stream = fopen("test.out", "wb")) != NULL)
fwrite(ptr, sizeof(ca), 1, stream);
else
printf("Problem opening for write\n");
fclose(stream);
memset((void *)&ca, 0, sizeof(ca));// zero the lot
if((stream = fopen("test.out", "rb")) != NULL)
fread((void*)ptr2, sizeof(ca), 1, stream);
else
printf("Problem opening for read\n");
return 0;
}
错误检查需要做像以前
是否有你需要的二进制格式的特别的原因?你不能使用简单的文本输出吗? – Sagar 2010-09-21 15:08:44
“...文件**快速重新加载**。可以...”哎呀,我错过了我第一次阅读这个问题时的快速点。与从(二进制)文件打开和读取所需的时间相比,从(ASCII)文本转换为任何类型所需的时间应该可以忽略不计。 – pmg 2010-09-21 15:42:38
如果你正在同一个平台上阅读和写作,那么你应该可以简单地调用write(2)。如果您要跨平台传输数据,则只需要担心数据格式。在这种情况下,我建议写入文本格式进行传输,然后在第一次使用之前将其转换为目标系统上的二进制文件。 – TMN 2010-09-21 16:11:35