【问题标题】:How to unpack a msgpack file?如何解压 msgpack 文件?
【发布时间】: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 的解包可以以某种方式直接从磁盘读取吗?还是有一些标准模式可以做到这一点?

【问题讨论】:

    标签: c file disk 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

      问候,夜鹰

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-01
        • 2021-03-15
        • 2017-01-19
        • 1970-01-01
        相关资源
        最近更新 更多