Я пытался применить итерацию к моему файлу leveldb, но, к сожалению, не смог получить результат. Проблема, с которой я столкнулся, - это ошибка сегментации при использовании указателя итератора. Я использовал gdb и понял, что проблема в строчке
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
(Я добавил несколько значений в этот файл / tem / userDb, и это добавление работает хорошо.)
#include <assert.h>
#include <leveldb/db.h>
#include <iostream>
#include <sstream>
using namespace std;
void iteration(leveldb::DB* db)
{
leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next())
{
cout << "key :" << it->key().ToString() << " : "
<< "value:" << it - > value().ToString() << endl;
}
if (false == it->status().ok())
{
cerr << "An error was found during the scan" << endl;
cerr << it->status().ToString() << endl;
}
delete it;
}
int main(int argc, char *argv[])
{
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
// erase error if the database exists
options.error_if_exists = true;
leveldb::Status s = leveldb::DB::Open(options, "/tmp/userDb", &db);
if (!s.ok())
cerr << s.ToString() << endl;
iteration(db);
delete db;
}
на самом деле я только что обнаружил, что это NULL, но я не знаю почему, потому что файл физически существует в моем / tmp
Не знаком с API leveldb
, но вы используете db
независимо от того, является ли s.ok()
true
или false
. Я бы предположил, что если s.ok()
- это false
, db
- это либо NULL
, либо в таком состоянии, что итерация или другие операции не будут работать.
Вам следует изменить код на:
if (!s.ok()) {
cerr << s.ToString() << endl;
return -1;
}
на самом деле вы правы, после добавления этого возврата -1 я не получил ошибку сегментации, но получил этот «Недействительный аргумент: / tmp / userDb: exists (error_if_exists is true)», потому что ясно, что программа завершилась возвратом -1, в чем может быть причина, по вашему мнению, сэр? Я не понимаю, почему указатель базы данных не работает, когда он физически существует в моих папках
@MadHer - Разве API, который вы используете, не имеет функции, возвращающей дополнительную информацию об ошибке? API, просто возвращающий true
или false
, не будет казаться надежным - должна быть дополнительная функция, которую вы бы вызывали для получения дополнительной информации, как только вы получите возвращаемое значение ошибки.
@PaulMcKenzie на самом деле нет, кроме s.ToString, я знаю, что проблема связана с db, потому что он существует, когда вы используете в первый раз, нет prblm (время создания), когда вы пытаетесь его открыть и для применения некоторых обновлений он больше не работает
@MadHer, у сообщения есть все, похоже, он жалуется, что база данных уже существует. Это происходит потому, что для options.error_if_exists
установлено значение true
. Установите его на false
, если это имеет смысл и не будет перезаписывать его.
@HoriaComan Я установил для него значение false и на самом деле предполагаю, что он работает, потому что больше нет ошибок о существовании db, спасибо за помощь, я обновлю его больше
Вы уверены, что
db
не являетсяNULL
после звонка наleveldb::DB::Open
?