2015-08-12 3 views
2

Я пишу msgpack-кодированные данные в файл. При написании я просто использую fbuffer API C. Как и в случае (в этом случае я перечеркнула всю обработку ошибок):Как распаковать файл msgpack?

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

Как прочесть этот файл? Весь пример, который я нашел, предполагает, что данные хранятся в памяти, однако мои файлы имеют размер до 5 ГБ, совсем не рекомендуется хранить это в памяти полностью. Также я не хочу читать куски. В конце концов, я не знаю, сколько времени у msgpack-объектов, поэтому, скорее всего, я получаю половину целого числа в моем буфере.

Может ли распаковка MSgpack как-то считываться с диска напрямую? Или есть какой-то стандартный шаблон для этого?

ответ

1

Возможно, вы захотите использовать вместо этого msgpack_unpacker, что, по-видимому, является официальным способом, которым MessagePack реализует дескриптор потоковой передачи. Посмотрите на msgpack-c/example/c/lib_buffer_unpack.c

С уважением, NiteHawk

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; 
} 

Я не пробовал, но я думаю, что он будет работать с более крупными объектами (массивы, карты и т. д.).

 Смежные вопросы

  • Нет связанных вопросов^_^