使用GVariant实现数据的序列化处理

内存中的大量数据如果要固化或跨进程传输,需要对数据进行序列化处理。使用GVariant除了可以描述数据自身的结构之外,还可以很容易的实现数据的序列化。下面的例子完成了一个自定义的5000条数据的序列化与恢复的过程:
1. 序列化5000条数据,数据内容是以字典方式存储的一个数据结构

#include <stdio.h>
#include <stdlib.h>
#include <glib.h>

/*
 * ===  FUNCTION  ======================================================================
 *         Name:  main
 *  Description:
 * =====================================================================================
 */
int main ( int argc, char *argv[] )
{
    int i;
    GVariant * _playlist;
    GVariantBuilder * _builder  =   g_variant_builder_new( G_VARIANT_TYPE( "av" ));
    gconstpointer _data;
    FILE * _fp;
    gsize _size;

    for( i = 0; i < 5000; i ++ )
    {
        GVariant * _item;
        GVariantBuilder * _itemBuilder  =   g_variant_builder_new( G_VARIANT_TYPE( "a{ss}" ));

        g_variant_builder_add( _itemBuilder, "{ss}", "location", "file:///tmp/00000001/1.mp3" );
        g_variant_builder_add( _itemBuilder, "{ss}", "name", "2.mp3" );
        g_variant_builder_add( _itemBuilder, "{ss}", "type", "mp3" );

        _item   =   g_variant_builder_end( _itemBuilder );

        g_variant_builder_add( _builder, "v", _item );
    }

    _playlist   =   g_variant_builder_end( _builder );

    _data   =   g_variant_get_data( _playlist );
    _size   =   g_variant_get_size( _playlist );

    _fp =   fopen( "/tmp/a.mhpl", "w" );

    fwrite( _data, _size, 1, _fp );

    fclose( _fp );

    g_variant_builder_unref( _builder );
    g_variant_unref( _playlist );

    return 0;
}               /* ----------  end of function main  ---------- */
2. 反序列化,将序列化的数据恢复后打印出来
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
/*
 * ===  FUNCTION  ======================================================================
 *         Name:  main
 *  Description:
 * =====================================================================================
 */
int main ( int argc, char *argv[] )
{
    FILE * _fp  =   fopen( "/tmp/a.mhpl", "r" );
    gsize _size;
    GVariant * _playlist;
    gpointer _data;
    GVariantIter * _iter;
    GVariant * _item;

    fseek( _fp, 0, SEEK_END );

    _size   =   ftell( _fp );

    _data   =   g_malloc0( _size );

    rewind( _fp );

    fread( _data, _size, 1, _fp );

    fclose( _fp );

    _playlist   =   g_variant_new_from_data( G_VARIANT_TYPE( "av" ), _data,
            _size, TRUE, NULL, NULL );

    _iter   =   g_variant_iter_new( _playlist );

    while( g_variant_iter_next( _iter, "v", &_item ))
    {
        gchar * _location, * _name, * _type;

        g_variant_lookup( _item, "location", "s", &_location );
        g_variant_lookup( _item, "name", "s", &_name );
        g_variant_lookup( _item, "type", "s", &_type );

        g_message( "%s, %s, %s", _location, _name, _type );

        g_variant_unref( _item );
        g_free( _location );
        g_free( _name );
        g_free( _type );
    }

    g_variant_iter_free( _iter );

    g_variant_unref( _playlist );

    return 0;
}               /* ----------  end of function main  ---------- */
3. 对于基于DBus方式实现的IPC,传输大量数据存在性能瓶颈。因此,可以基于上面的方式,将数据序列化后,由pipe或socket传输的方式在进程间传递,在性能上可以获得极大提升


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值