如何解压 msgpack 文件?
How to unpack a msgpack file?
我正在将 msgpack 编码的数据写入文件。在写作上,我只是使用CAPI的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 的解压能否以某种方式直接从磁盘读取?或者是否有一些标准模式可以做到这一点?
好的,我成功了。
写法如下:
#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;
}
我没有尝试过,但我认为它也适用于更大的对象(数组、映射等)。
您可能会考虑使用 "msgpack_unpacker" 作为代替,这似乎是 MessagePack 实现 'streaming' 反序列化器的官方方式。看看 msgpack-c/example/c/lib_buffer_unpack.c
此致,NiteHawk
我正在将 msgpack 编码的数据写入文件。在写作上,我只是使用CAPI的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 的解压能否以某种方式直接从磁盘读取?或者是否有一些标准模式可以做到这一点?
好的,我成功了。
写法如下:
#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;
}
我没有尝试过,但我认为它也适用于更大的对象(数组、映射等)。
您可能会考虑使用 "msgpack_unpacker" 作为代替,这似乎是 MessagePack 实现 'streaming' 反序列化器的官方方式。看看 msgpack-c/example/c/lib_buffer_unpack.c
此致,NiteHawk