长数组的序列化(在C中)
在C程序中,我要序列化一个long *(因此转换为char)。 long不能容纳在单个char中,并且大小取决于处理器(可以是4个字节或者8个字节)。
是否有进行序列化和反序列化的好方法?
解决方案
如果创建一个指向长数组开头的char指针,则当通过char" array"递增时,一次将获得8位。但是请注意,long不会以空值终止(有必要,可能会是null),因此我们需要跟踪其结尾在哪里。
例如:
long list[MAX]; char *serial = list; int chunk = sizeof(long); int k; for(k=0; k<(MAX*chunk); k++){ // do something with the "char" }
long * longs; // ... int numChars = numLongs * sizeof(long); char* longsAsChars = (char*) longs; char* chars = malloc(numChars); memcpy(chars, longsAsChars, numChars);
在C中,我们可以使用
sizeof(long)
但是,如果我们存储的long必须在多个平台之间转移,则应始终将其序列化为4个字节。无论如何,4字节处理器无法读取更大的数字。
我们可能正在解决错误的问题。我们应该使用int32_t序列化为固定大小的int。我们可能希望在整个程序中使用这种固定大小的类型,否则当64位程序无法保存为较小的大小(或者使用int64_t)时,我们将遇到问题。
如果知道我们永远不必在32位平台上加载64位保存文件,那么就不必理会。只需将sizeof(long)个字节写出到文件中,然后读回sizeof(long)个字节即可。但是,请在数据中早些标记一个指示源平台的标记,以免出错。
我们不必序列化为char,就可以将long写入(到文件)。要序列化为char数组,请在开头添加一个字节,以指示int的大小和字节顺序,稍后我们将需要使用此字节。
IE。
char *p = &long_array[0];
要以char形式访问long数组,只需将其强制转换并将数组的长度乘以sizeof(long)即可获得char的大小。
一个简单的例子说明了这一点:
#include <stdio.h> main() { int aaa[10]; int i; char *p; for(i=0;i<sizeof(aaa)/sizeof(aaa[0]);i++) { aaa[i] = i; printf ("setting aaa[%d] = %8x\n",i,aaa[i]); } aaa[9] = 0xaabbccdd; printf ("sizeof aaa (bytes) :%d\n",sizeof(aaa)); printf ("each element of aaa bytes :%d\n",sizeof(aaa[0])); p = (char*) aaa; for(i=0;i<sizeof(aaa);i++) printf ("%d: %8x\n",i,(unsigned char)p[i]); }
这是可移植的,但是效率远不及使用printf / scanf
void longtochar(char *buffer, unsigned long number) { int i; for (i=0; i<sizeof(long); i++) { buffer[i] = number & 0xFF; // place bottom 8 bits in char number = number >> 8; // shift down remaining bits } return; // the long is now stored in the first few (2,4,or 8) bytes of buffer }
并再次打开包装(假设长为相同尺寸)
long chartolong(char *buffer) { long number = 0; int i; for (i=sizeof(long)-1; i>=0; i--) { number = number << 8; // left shift bits in long already number += buffer[i]; // add in bottom 8 bits } return number; }
请注意BIG的假设,即两个系统上的long长度相同。安全的做法是#include <stdint.h>并使用其提供的类型(uint32_t或者uint16_t)。
另外,我的代码将其设置为无符号长整数。我现在无权使用C编译器,因此我无法确认它是否适用于带符号整数。如果记忆为我服务,则它的行为可能是不确定的(尽管可能无关紧要,我如何处理它)。