Мне нужно обновить индекс (в формате JSON) при записи нового файла на диск, и, поскольку файлы распределены по категориям, я использую объект с такой структурой:
{ "type_1" : [ "file_1", "file_2" ], "type_2" : [ "file_3", "file_4" ] }
Я думал, что это простая задача для jsoncpp, но я, вероятно, что-то упустил.
Мой код (упрощенный) здесь:
std::ifstream idx_i(_index.c_str());
Json::Value root;
Json::Value elements;
if (!idx_i.good()) { // probably doesn't exist
root[type] = elements = Json::arrayValue;
} else {
Json::Reader reader;
reader.parse(idx_i, root, false);
elements = root[type];
if (elements.isNull()) {
root[type] = elements = Json::arrayValue;
}
idx_i.close();
}
elements.append(name.c_str()); // <--- HERE LIES THE PROBLEM!!!
std::ofstream idx_o(_index.c_str());
if (idx_o.good()) {
idx_o << root;
idx_o.close();
} else {
Log_ERR << "I/O error, can't write index " << _index << std::endl;
}
Итак, я открываю файл, чтение данных JSON работает, если я не могу их найти, я создаю новый массив, проблема в том, что: когда я пытаюсь добавить значение в массив, это не работает, массив остается пустым и записывается в файл.
{ "type_1" : [], "type_2" : [] }
Попытался отладить мой код, и jsoncpp вызывает, и все вроде бы нормально, но массив всегда пуст.
Проблема возникает здесь:
elements = root[type];
потому что вы создаете копия из root[type]
при вызове этого API JsonCpp:
Value &Value::operator[]( const std::string &key )
таким образом, не модифицируя root
документ вообще. Самый простой способ избежать этой проблемы — в вашем случае не использовать elements
переменная:
root[type].append(name.c_str());
Других решений пока нет …