首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LevelDB C迭代器

LevelDB C迭代器
EN

Stack Overflow用户
提问于 2016-03-28 12:34:07
回答 2查看 2.1K关注 0票数 2

我需要用c语言- https://github.com/google/leveldb/blob/master/include/leveldb/c.h来遍历leveldb数据库。除了iterating.The结果之外,一切正常运行的是一些二进制噪声数据:

代码语言:javascript
复制
key: value1
key: value2
key#&^$&*# value
one1(*@(# value1
two2%*@( value2

使用$&*#等符号,我展示了二进制输出,堆栈溢出不允许将二进制输出放在这里。

守则:

代码语言:javascript
复制
#include <leveldb/c.h>
#include <stdio.h>

int main() {
    leveldb_t *db;
    leveldb_options_t *options;
    leveldb_readoptions_t *roptions;
    leveldb_writeoptions_t *woptions;
    char *err = NULL;
    char *read;
    size_t read_len;

    /******************************************/
    /* OPEN */

    options = leveldb_options_create();
    leveldb_options_set_create_if_missing(options, 1);
    db = leveldb_open(options, "testdb", &err);

    if (err != NULL) {
      fprintf(stderr, "Open fail.\n");
      return(1);
    }

    /* reset error var */
    leveldb_free(err); err = NULL;

    /******************************************/
    /* WRITE */

    woptions = leveldb_writeoptions_create();
    leveldb_put(db, woptions, "one", 3, "value1", 6, &err);

    if (err != NULL) {
      fprintf(stderr, "Write fail.\n");
      return(1);
    }

    leveldb_free(err); err = NULL;

    /******************************************/
    /* WRITE 2 */

    woptions = leveldb_writeoptions_create();
    leveldb_put(db, woptions, "two", 3, "value2", 6, &err);

    if (err != NULL) {
      fprintf(stderr, "Write fail.\n");
      return(1);
    }

    leveldb_free(err); err = NULL;

    /******************************************/
    /* READ */

    roptions = leveldb_readoptions_create();
    read = leveldb_get(db, roptions, "one", 3, &read_len, &err);

    if (err != NULL) {
      fprintf(stderr, "Read fail.\n");
      return(1);
    }

    printf("key: %s\n", read);

    leveldb_free(err); err = NULL;

    /******************************************/
    /* READ 2 */

    roptions = leveldb_readoptions_create();
    read = leveldb_get(db, roptions, "two", 3, &read_len, &err);

    if (err != NULL) {
      fprintf(stderr, "Read fail.\n");
      return(1);
    }

    printf("key: %s\n", read);

    leveldb_free(err); err = NULL;

    /******************************************/
    /* ITERATE */

    roptions = leveldb_readoptions_create();
    leveldb_iterator_t *iter = leveldb_create_iterator(db, roptions);

    for (leveldb_iter_seek_to_first(iter); leveldb_iter_valid(iter); leveldb_iter_next(iter))
    {
        size_t key_len, value_len;
        const char *key_ptr = leveldb_iter_key(iter, &key_len);
        const char *value_ptr = leveldb_iter_value(iter, &value_len);

        /* Prints some binary noise with the data */
        printf("%s %s\n", key_ptr, value_ptr);
    }
    leveldb_iter_destroy(iter);
    leveldb_free(err); err = NULL;

    /******************************************/
    /* CLOSE */

    leveldb_close(db);

    return(0);
}

如何在C语言中正确地迭代LevelDB?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-28 13:00:48

leveldb_iter_keyleveldb_iter_value返回的值似乎是不正确的以空结尾的字符串。

所以,肮脏的解决方案将被使用

代码语言:javascript
复制
printf("%.*s %.*s\n", (int) key_len, key_ptr, (int) value_len, value_ptr);

而不是

代码语言:javascript
复制
printf("%s %s\n", key_ptr, value_ptr);

然而,海事组织最好根据它们的长度复制这些值,然后使用它们。

正如您在https://github.com/google/leveldb/blob/master/db/c.cc#L197中看到的,leveldb_get创建适当长度的切片(Slice(key, keylen) on L205)并返回密钥的副本(CopyString on L208)。

附加信息:

我已经检查了您的代码,并有一些选项的内存泄漏。您应该手动释放它们(例如,leveldb_writeoptions_destroy用于woptions)。还应该释放leveldb_get结果(read)。

示例代码:

代码语言:javascript
复制
// allocate new strings
char * key = (char *) malloc(key_len + 1);
char * value = (char *) malloc(value_len + 1);

// copy string content and ensure that string is null-terminated
memcpy(key, key_ptr, key_len);
key[key_len] = 0;
memcpy(value, value_ptr, value_len);
value[value_len] = 0;

// print
printf("%s %s\n", key, value);

// free
free(key);
free(value);
票数 2
EN

Stack Overflow用户

发布于 2018-09-19 14:19:06

LevelDB不使用C(++)字符串作为键和值,它使用字节数组,这些字节数组可能包含NULs,并且不以NUL结尾。这里记录了这一点:1

使用任何面向C字符串的函数来操作这些数组都是错误的。不能使用printf安全地显示返回的值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36262408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档