长数组的序列化(在C中)

时间:2020-03-06 15:02:41  来源:igfitidea点击:

在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编译器,因此我无法确认它是否适用于带符号整数。如果记忆为我服务,则它的行为可能是不确定的(尽管可能无关紧要,我如何处理它)。