如何使用C++合并两个含大量记录的JSON文件?
合并JSON数组文件的JsonCpp解决方案
问题说明
我有两个各包含10万条记录的JSON文件,每条记录包含city、name、job、email、salary五个字段,文件格式为JSON数组:
[ { "city":"Lisbon", "name":"Shannon Ward", "job":"Ambulatory Nurse", "email":"Shannon_Ward6180@6ijur.works", "salary":"2308593.84555454" }, { "city":"Lancaster", "name":"Kurt Hopkinson", "job":"Lecturer", "email":"Kurt_Hopkinson235@nb44i.digital", "salary":"8564088.47550575" } ]
使用JsonCpp库尝试合并时,编写了以下代码:
Json::Value records1; Json::Value records2; Json::Reader reader; reader.parse(file1, records1); // file1是第一个JSON文件的输入流 reader.parse(file2, records2); // file2是第二个JSON文件的输入流 for (auto& itr : records2) records1.append(itr);
编译器报错:
C++ no instance of overloaded function matches the argument list and object (the object has type qualifiers that prevent a match)
argument types are: (const Json::Value)
object type is: const Json::Value
错误原因
范围for循环遍历Json::Value数组时,返回的迭代器是const Json::Value&类型,而Json::Value::append()方法要求传入非const的Json::Value&,类型不匹配导致编译失败。
修正后的代码
方案1:传递副本给append
将循环中的auto&改为auto,生成非const的副本传递给append():
Json::Value records1; Json::Value records2; Json::Reader reader; reader.parse(file1, records1); reader.parse(file2, records2); // 使用auto生成非const副本 for (auto itr : records2) records1.append(itr);
方案2:下标遍历获取非const引用
通过下标直接访问records2的元素,避免const引用问题:
Json::Value records1; Json::Value records2; Json::Reader reader; reader.parse(file1, records1); reader.parse(file2, records2); for (int i = 0; i < records2.size(); ++i) { records1.append(records2[i]); }
大文件优化建议
由于两个文件各有10万条记录,全量加载到内存会占用较多资源。可以采用流式处理,无需加载所有数据到内存:
#include <fstream> #include <string> int main() { std::ifstream file1("file1.json"); std::ifstream file2("file2.json"); std::ofstream out("merged.json"); // 写入第一个文件内容,去掉末尾的] std::string content1((std::istreambuf_iterator<char>(file1)), std::istreambuf_iterator<char>()); size_t end_pos = content1.find_last_of(']'); if (end_pos != std::string::npos) { content1 = content1.substr(0, end_pos); out << content1 << ","; } // 写入第二个文件内容,去掉开头的[和末尾的] std::string content2((std::istreambuf_iterator<char>(file2)), std::istreambuf_iterator<char>()); size_t start_pos = content2.find_first_of('['); end_pos = content2.find_last_of(']'); if (start_pos != std::string::npos && end_pos != std::string::npos) { content2 = content2.substr(start_pos + 1, end_pos - start_pos - 1); out << content2 << "]"; } return 0; }
注意:该方法要求JSON文件格式严格规范,无额外的语法错误或格式异常。
内容的提问来源于stack exchange,提问作者Akash Rajawat
相关产品推荐
相关产品推荐

