内存中的大量数据如果要固化或跨进程传输,需要对数据进行序列化处理。使用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传输的方式在进程间传递,在性能上可以获得极大提升