帮别人做设计图的网站,内网站做映射,大学做视频网站,做家政有什么网站做推广好Boost社区12月11日发布了1.75版本#xff0c;在之前#xff0c;Boost使用Boost.PropertyTree解析JSON#xff0c;XML#xff0c;INI和INFO格式的文件。但是由于成文较早及需要兼容其他的数据格式#xff0c;相比较于其他的…Boost社区12月11日发布了1.75版本在之前Boost使用Boost.PropertyTree解析JSONXMLINI和INFO格式的文件。但是由于成文较早及需要兼容其他的数据格式相比较于其他的C解析库使用时不方便。
Boost.JSON相对于Boost.PropertyTree来所其只能支持JSON格式的解析但是其使用方法更为简便直接。
有两种方法使用Boost.JSON一种是动态链接库此时引入头文件boost/json.hpp同时链接对应的动态库第二种是使用header only模式此时只需要引入头文件boost/json/src.hpp即可。
数据类型
array
数组类型用于储存JSON中的数组。实际使用的时候类似于std::vectorboost::json::value差异极小。
object
object是JSON键值对的容器对象类型用于储存JSON中的对象。实际使用时类似于std::mapstd::string, boost::json::value但是相对来说它们之间的差异较大。定义在boost/json/object.hpp
项目Valueat(key)获取指定Key对应的元素的引用不存在时会抛出out_of_range异常begin/end获取iteratorcapacity容量cbegin/cend获取const iteratorclearErase all elements.contains(key)判断Key是否存在count(key)返回Key的数量emplaceConstruct an element in-place.empty是否为空erase(it/key)根据key或iterator移除元素find(key)返回指定key的iterator或end()。if_contains(key)返回key对应value的指针或null不存在时。insert插入元素insert_or_assign插入或赋值若key已存在operatorCopy assignment.Move assignment.Assignment.operator[]存在返回对应引用若不存在则插入null value并返回reserve增加容量若指定值小于现有容量则什么也不做size大小swapSwap two objects.max_size静态成员返回object能保存元素的最大数量。
string
字符串类型用于储存JSON中的字符串。实际使用时和std::basic_string类似不过其只支持UTF-8编码如果需要支持其他编码在解码时候需要修改option中相应的选项。
value
表示JSON值的类型可以储存任意类型也可以变换为各种类型。其中有一些特色的函数比如as_objectget_arrayemplace_int64之类的。它们的工作都类似将boost::json::value对象转化为对应的类型。但是他们之间也有一定的区别。
构造json
{a_string : test_string,a_number : 123,a_null : null,a_array : [1, 2, {123 : 123}],a_object : {a_name: a_data},a_bool : true
}构造的方法也很简单定义一个object然后设定各个value即可
boost::json::object val;
val[a_string] test_string;
val[a_number] 123;
val[a_null] nullptr;
val[a_array] {1, 2, boost::json::object({{123, 123}})
};
val[a_object].emplace_object()[a_name] a_data;
val[a_bool] true;Boost.JSON支持使用std::initializer_list来构造自己的对象。所以也可以这样使用
boost::json::value val2 {{a_string, test_string},{a_number, 123},{a_null, nullptr},{a_array, {1, 2, {{123, 123}}}},{a_object, {{a_name, a_data}}},{a_bool, true}
};但是使用initializer_list构造时有时很难区分是数组还是对象可以明确指定
// 构造[[data, value]]
boost::json::value jsonAry {boost::json::array({data, value})};// 构造{data: value}
boost::json::value jsonObj boost::json::object({{data, value}});序列化
生成了json对象以后就可以使用serialize对对象进行序列化了。
std::cout boost::json::serialize(val2) std::endl;除了直接把整个对象直接输出Boost.JSON还支持分部分进行流输出这种方法在数据量较大时可以有效降低内存占用。
boost::json::serializer ser;
ser.reset(val);char temp_buff[6];
while (!ser.done()) {std::memset(temp_buff, 0, sizeof(char) * 6);ser.read(temp_buff, 5);std::cout temp_buff std::endl;
}如果缓存变量是数组还可以直接使用ser.read(temp_buff)。
需要注意的是ser.read并不会默认在字符串末尾加\0所以如果需要直接输出在输入时对缓存置0同时为\0空余一个字符。
也可以直接使用输出的boost::string_view。
对象序列化
对象转换为JSONBoost.JSON提供了一个非常简单的方法只需要在需要序列化的类的命名空间中定义一个重载函数tag_invoke是类所在的命名空间而不是在类里面定义然后通过value_from即可方便地序列化对象了
namespace NSJsonTest {class MyClass {public:int a;int b;MyClass (int a 0, int b 1):a(a), b(b) {}};void tag_invoke(boost::json::value_from_tag, boost::json::value jv, MyClass const c) {auto jo jv.emplace_object();jo[a] c.a;jo[b] c.b;}MyClass myObj;auto jv boost::json::value_from(myObj)
}其中boost::json::value_from_tag是作为标签存在的方便Boost.JSON分辨序列化函数的。jv是输出的JSON对象c是输入的对象。
boost::json::value_from(MyObj)使用的话直接调用value_from函数即可。 序列化还有一个好处就是可以在使用std::initializer_list初始化JSON对象时直接使用自定义对象。譬如
boost::json::value val {MyObj};这里的val是一个数组里面包含了一个对象MyObj。
反序列化
使用boost::json::parse
auto decode_val boost::json::parse({\123\: [1, 2, 3]});增加错误处理
boost::json::error_code ec;
boost::json::parse({\123\: [1, 2, 3]}, ec);
std::cout ec.message() std::endl;boost::json::parse({\123\: [1, 2, 3}, ec);
std::cout ec.message() std::endl;对象反序列化
与对象序列化对应的是对象反序列化也是在命名空间中定义个tag_invoke函数然后即可通过value_to把JSON对象反序列化为类对象了
MyClass tag_invoke(boost::json::value_to_tagMyClass, boost::json::value const jv) {auto jo jv.as_object();return MyClass(jo.at(a).as_int64(), jo.at(b).as_int64());
}// jv为前面序列化时的对象
auto myObj boost::json::value_toMyClass(jv);需要注意的是由于传入的jv是被const修饰的所以不能类似于jv[“a”]使用。
使用也和上面的类似提供了一个value_to模板函数。
auto MyObj boost::json::value_toMyNameSpace::MyClass(vj);无论是序列化还是反序列化对于标准库中的容器Boost.JSON都可以直接使用。
流输入
通过stream_parser可以流的方式读入要解析的字符串
boost::json::stream_parser p;
p.reset();p.write([1, 2,);
p.write(3]);
p.finish();std::cout boost::json::serialize(p.release()) std::endl;示例
json文件
#include boost/json.hpp
#include boost/json/src.hpp
#include iostream
#include iterator
#include fstream
namespace json boost::json;struct Rec {int64_t number;std::string string;friend Rec tag_invoke(json::value_to_tagRec, json::value const v) {auto o v.as_object();return {o.at(number).as_int64(),boost::json::value_tostd::string(o.at(string)),};}friend void tag_invoke(json::value_from_tag, json::value v, Rec const rec){v json::object{{number, rec.number},{string, rec.string},};}
};int main() {std::ifstream ifs(../input.json);std::string input(std::istreambuf_iteratorchar(ifs), {});using Recs std::vectorRec;Recs recs boost::json::value_tostd::vectorRec(json::parse(input));for (auto [n, s] : recs) {std::cout Rec { n , std::quoted(s) }\n;// some frivolous changes:n * 2;reverse(begin(s), end(s));}std::cout Modified json: json::value_from(recs) \n;
}参考 Boost.JSON Boost的JSON解析库