如何解压 msgpack 文件?

Posted

技术标签:

【中文标题】如何解压 msgpack 文件?【英文标题】:How to unpack a msgpack file? 【发布时间】:2015-11-05 07:35:50 【问题描述】:

我正在将 msgpack 编码的数据写入文件。在写作时,我只是使用 C API 的 fbuffer。如(我为示例删除了所有错误处理):

FILE *fp = fopen(filename, "ab");
msgpack_packer pk;
msgpack_packer_init(pk, fp, msgpack_fbuffer_write);
msgpack_pack_int(pk, 42);
// more data ...

我如何读回这个文件?我发现的所有示例都假设数据在内存中,但是,我的文件最大为 5GB,将其完全保存在内存中并不是一个好主意。我也不想自己分块阅读。毕竟,我不知道 msgpack 对象有多长,所以我很可能会在缓冲区中得到半个整数。

msgpack 的解包可以以某种方式直接从磁盘读取吗?还是有一些标准模式可以做到这一点?

【问题讨论】:

【参考方案1】:

好的,我设法做到了。

写法如下:

#include <stdlib.h>
#include <msgpack.h>
#include <msgpack/fbuffer.h>

int main(int argc, char **argv) 
    if(2 != argc) 
            fprintf(stderr, "Call all writeFile <file>");
            return;
    

    FILE *fp = fopen(argv[1], "ab");
    msgpack_packer pk;
    msgpack_packer_init(&pk, fp, msgpack_fbuffer_write);

    for(int i=0;i<2048;i++) 
            msgpack_pack_int(&pk, i);
    
    fclose(fp);

这就是阅读的样子:

#include <stdlib.h>
#include <msgpack.h>

static const int BUFFERSIZE = 2048;

int main(int argc, char **argv) 
    if(2 != argc) 
            fprintf(stderr, "Call with readFile <file>");
            return 1;
    

    char *inbuffer = (char *) malloc(BUFFERSIZE);
    if(NULL == inbuffer) 
            fprintf(stderr, "Out of memory!");
            return 1;
    

    FILE *fp = fopen(argv[1], "rb");
    size_t off = 0;
    size_t read = 0;
    msgpack_unpacked unpacked;
    msgpack_unpacked_init(&unpacked);
    do 
            read = fread(inbuffer, sizeof(char), BUFFERSIZE - off, fp);
            off = 0;
            while(msgpack_unpack_next(&unpacked, inbuffer, read, &off)) 
                    msgpack_object_print(stdout, unpacked.data);
                    puts("");
            
            memcpy(inbuffer, &(inbuffer[off]), read-off);
            off = read - off;
     while(read != 0);
    free(inbuffer);
    fclose(fp);
    msgpack_unpacked_destroy(&unpacked);
    return 0;

我没有尝试,但我认为它也适用于更大的对象(数组、地图等)。

【讨论】:

【参考方案2】:

您可能会考虑使用“msgpack_unpacker”来代替,这似乎是 MessagePack 实现“流式”反序列化器的官方方式。看看 msgpack-c/example/c/lib_buffer_unpack.c

问候,夜鹰

【讨论】:

以上是关于如何解压 msgpack 文件?的主要内容,如果未能解决你的问题,请参考以下文章

json,serialize,msgpack比较

如何在 python 中使用 msgpack 打包数组?

我如何使用 msgpack 读写?

kafka-msgpack-json: 将msgpack和protobuf转化成json

msgpack可以提供更好的性能和相同的python的struct.pack()功能吗?

msgpack 能否提供更好的性能和与 python 的 struct.pack() 相同的功能?