- 论坛徽章:
- 0
|
本帖最后由 newzy 于 2011-03-09 13:00 编辑
用 JSON 保存后台配置数据
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/newzy/archive/2011/03/08/6232832.aspx
在前台数据交换中,优其 web应用领域,JSON以其简单性和可扩展性“大有替代”xml 之势(夸张地说)。
本文简单介绍了 json 作为配置的存取在后台操作的便利性,希望本文能抛砖引玉,让JSON给大家后台配置存取提供更多便利。
编辑器: JSON 在线编辑器 JsonEditor V1.03.2
在一些中/小型应用程序中,配置文件是必须的。采用什么格式的配置文件一直困扰着很多开发人员。实践中常用的有四种类型:
1) 采用 c/c++ 的结构体存储。
虽然很原始,便还是在很多场景可以看到,原因是免解析。缺点太多了,比如不易扩展,可读性差。
2)采用 "名称 = 值" 的行存储,或类似 windows 系统 ini 文件的格式。 通过 xxx_set/xxx_get 的方法进行存取.
在各种应用中都很常见,优其小型嵌入式设备上很多时候配置采用类似的方法。
3)采用相对复杂的分段/分级配置。
如 Apache/Ngix 等的配置文件,再如 cisco 的 consle 配置。优点时文本方式,便于编辑,有良好的结构性。
缺点解析起来相对复杂,需要为应用定制配置格式。
4)采用 xml 格式保存配置。
在大型应用,优其 java,.net 的项目中应用的优其多。原因是平台或操作语言提供了 xml 的操作 API。
在小型 c/c++ 程序中, 如果你有 DOM/XML 的操作 API, 依然是是可行的。
最近在一些小型项目的实践中, 保存配置文件,我是越来越倾向于使用 JSON 了。原因是
1) JSON 像 XML 一样有的良好结构性。
2) JSON 固有的数据类型 object/string/number/true/false 意义明确,便于表达.
3) JSON 语法简单,解析器易实现,同时便于解析和格式化输出。(JSON的官方站点上有各种语言的解析器)
4) 配置层次性好,最近又修改了一个开源 JSON "树型" 编辑器。用工具编辑配置文件,感觉很省事。
说了这多, 还未到正文。下来用示例来说明下吧。后文件示例以 c 代码作为伪代码展示。
假设你已经有如下 JSON 的操作 API (如果没有可以很容易自己实现封装):
1) json_t /*json 类型 */
2) json_t * json_parse_string(const char * json_string); /* 解析 json 树 */
3) const char * json_get_name(json_t * json, const char * path); /* 获取节点名 */
4) const char * json_get_str(json_t * json, const char * path); /* 获取节点值:string 类型 */
5) const char * json_get_int(json_t * json, const char * path); /* 获取节点值:int 类型 */
6) FOREACH_IN_JSON_CHILD(json, path, pchild) /* 宏用于遍历子节点 */
以下为假想配置示例:
- {
- "Root":"F:/website/doc",
- "Connection":{
- "maxconnects":1500,
- "maxkeepalive":0,
- "keeptimeout":15,
- },
- "Listen":[{
- "ip":"0.0.0.0",
- "port":"8088",
- "protocol":"http",
- "maxlisten":"100"
- },
- {
- "ip":"127.0.0.1",
- "port":"8090",
- "protocol":"http",
- "maxlisten":"100"
- }],
- "Directory":{
- "/app/":{
- "path":"F:/website/doc",
- "RewriteRule":[{
- "from":"",
- "to":"{}"
- },
- {
- "from":"",
- "to":"{}"
- }]
- },
- "/libso/":{
- "path":"E:/eybuild/lib6/app/",
- "RewriteRule":[{
- "from":"",
- "to":"{}"
- },
- {
- "from":"",
- "to":"{}"
- }]
- },
- }
- },
- "DAction":[
- "/libso/*.so",
- "/libso/*.dll",
- "/dll/*.dll"],
- "SAction":[
- "/app/**",
- "/bbr/",
- "/cplus/"],
- "Log":{
- "Logfile":"c:/log/log.log",
- "Loglevel":5
- }
- }
- {
- "Root":"F:/website/doc",
- "Connection":{
- "maxconnects":1500,
- "maxkeepalive":0,
- "keeptimeout":15,
- },
- "Listen":[{
- "ip":"0.0.0.0",
- "port":"8088",
- "protocol":"http",
- "maxlisten":"100"
- },
- {
- "ip":"127.0.0.1",
- "port":"8090",
- "protocol":"http",
- "maxlisten":"100"
- }],
- "Directory":{
- "/app/":{
- "path":"F:/website/doc",
- "RewriteRule":[{
- "from":"",
- "to":"{}"
- },
- {
- "from":"",
- "to":"{}"
- }]
- },
- "/libso/":{
- "path":"E:/eybuild/lib6/app/",
- "RewriteRule":[{
- "from":"",
- "to":"{}"
- },
- {
- "from":"",
- "to":"{}"
- }]
- },
- }
- },
- "DAction":[
- "/libso/*.so",
- "/libso/*.dll",
- "/dll/*.dll"],
- "SAction":[
- "/app/**",
- "/bbr/",
- "/cplus/"],
- "Log":{
- "Logfile":"c:/log/log.log",
- "Loglevel":5
- }
- }
-
复制代码 1) 加载配置文件,解析成 JSON 树.
readfile(conf_buf, from_file); /*加载配置 */
json_t * jcon = json_parse_string(conf_buf);
2)遍历第一层配置。
json_t * jobj;
FOREACH_IN_JSON_CHILD(jconf, "", jobj)
{
const char * pname = json_get_name(jobj));
const char * pvalue = json_get_str(jobj);
if (compare("Root", pname))
call_xxx_set_root(); /* 把值传给处理函数 */
else if (compare("Connection", pname))
call_xxx_set_connection(); /* 把值传给处理函数 */
else if (compare("Listen", pname))
call_xxx_set_listen(jobj); /* 把值传给处理函数 */
.... /* 其它节点 */
}
3)对子节点进行处理,以 Listen 数组下的结点为例。
从上面我们可以看到 Listen是个数组,其下的节点数目是不确定的,依然使用 foreach 的形式进行遍历.
int call_xxx_set_lisen(json_t * jconf)
{
json_t * jobj;
/* 从数组中取出一个节点 */
FOREACH_IN_JSON_CHILD(jconf, "", jobj)
{
/* 对数组中的每一个原素 */
const char * ip = json_get_name(jobj, "ip"));
short int port = json_get_int(jobj, "port");
.... /* 这里加上应用该配置的函数 */
}
}
4)其它节点类似。
小结:
JSON 的如下特性决定了 json 非常适合配置存储:
1) JSON 具有良好的树型结构,便于程序操作。
2) JSON 对像的值可以是一个普通对象也可以是一个“集合”或数组,使用FOREACH_IN_JSON_CHILD()的形式对子节点遍历。
3) JSON 对象便于序列化成字符串存储/传递.
4) JSON 便于解析/格式化
5) 因为天太晚了该睡了,此处略去 nK 字吧, 呵呵
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/newzy/archive/2011/03/08/6232832.aspx |
|