开源中文网

您的位置: 首页 > 数据库应用 > Berkeley DB > 正文

如何在Berkeley DB 中存储C++结构体

来源:  作者:

介绍

   Berkeley DB适合存储简单的数据,比如那些c/c++定义的类型,诸如int、float、char 和wchar_t等等。因为DB 虽然可以存入任意类型的数据,但是它只会原原本本按照字节将数据存入(entirely 8-bit clean data),其它的工作需要我们自己负责。
   如果我们定义了一个只包含简单数据类型属性的结构体,且我们给这个结构体对象赋值的时候,每个属性都不是动态分配内存的,那我们直接使用Db::put 方法可以将其存入数据库中,且简单的Db::get 后强制转换就能将其还原出来——可是这在实际开发中几乎是不可能的。所以在将structure object存入DB的时候我们需要做更多的工作——我们需要将这个对象转换为字节数组unsigned char 的array,然后再存入DB 中;get 数据的时候需要将这个array再还原为我们的structure object,有术语来指明它们:marshalling和un-marshalling。除此之外,还有一个办法,就是使用二进制的序列化和反序列化。
 
Marshalling and Un-marshalling
这是一种比较麻烦的办法,也是一种非常不灵活,不美观的方式,但是它是有效的。使用 run-length 的方式——先将属性的长度存入array 中,然后再将此属性使用内存拷贝的方式存入array;还原的时候先取得长度,然后根据此长度得到此属性的值。例子:

unsigned int GetSize()
{
    unsigned int size = 0;
    size += sizeof(size);
    size += wcslen(Name)*2+2;
    size += sizeof(size);
    size += wcslen(Description)*2+2;
    return size;
}

//Marshall the struct to a run-length byte array
unsigned int Marshall(unsigned char* buffer)
{
    size_t bytesCount=GetSize();
    size_t len = 0;
    unsigned char *p;
    memset(buffer,0,bytesCount);
    p = &buffer[0];
    //Name

    len = wcslen(Name)*2+2;
    memcpy(p,&len,sizeof(len));//id length

    p+=sizeof(len);
    memcpy(p,Name,len);
    p+=len;
    //description

    len = wcslen(Description)*2+2;
    memcpy(p,&len,sizeof(len));//id length

    p+=sizeof(len);
    memcpy(p,Description,len);
    p+=len;
    return bytesCount;
}

//Unmarshall the byte array to struct
void Unmarshall(unsigned char* buffer)
{
    unsigned char* p;
    size_t len = 0;
    p = &buffer[0];


    //Name
     memcpy(&len,p,sizeof(len));
    p+= sizeof(len);
    Name = (wchar_t*)malloc(len);
    memcpy(Name,p,len);
    p+= len;


    //Description
     memcpy(&len,p,sizeof(len));
    p+= sizeof(len);
    Description = (wchar_t*)malloc(len);
    memcpy(Description,p,len);
    p+= len;
}

使用Marshall来得到byte array,将此byte array存入DB。而从DB中get到byte array后,只需要使用Unmarshall方法就可以还原该structure object了。缺点显而易见:如果的struct变动了,多处代码都需要变动,代码比较繁复冗长,特别是当struct的属性比较多的时候。
 
Serialization and Un-serialization
序列化和反序列化已经是普遍使用的技术了,我们可以使用该技术将对象转换为byte array(或者text),和将byte array(或者text)还原为对象。序列化和反序列化的方法有很多,根据实际情况选择合适的方法。如出现频率比较高的例子:http://www.moon-soft.com/doc/38473.htm

Tags:结构
相关文章列表:
关于开源中文网 - 联系我们 - 广告服务 - 网站地图 - 版权声明