看一下windows的ini格式配置文件:
[startup]
cmd=a.bat
para=...
...
windows的配置都是诸如上述的ini文件,格式如下:
[section]
name=value
...
这种配置文件虽然没有二进制文件那般无耻可毕竟也是“格式化”的,比如上面的"[","]","="等都是格式,这种“格式”定义得越多,处理它的程序就越复杂和专业,最终随着配置文件的复杂化,处理程序也最终变成了诸如word之类的庞然大物,所以说,尽可能不要定义格式太复杂的配置文件,程序不应该将大量逻辑用于处理文件IO,因此尽可能保持配置文件的简单性,正如unix的文本配置文件那样,没有section,以行为单位,每次处理一行。处理程序可以十分简单,以一个while循环为大框架,里面就是一个状态机,每一行就是状态机的一个状态,同时每一行也是一个子状态机,解析程序控制这两个状态机向前推进,直到文件被处理完毕,下面是一个经典的配置文件处理框架:
static void read_config_file (...)
{
int line_num;
char line[OPTION_LINE_SIZE]; //配置文件的一行
char *p[MAX_PARMS]; //配置文件一行转化而成的有意义的数组
fp = fopen (file, "r");
line_num = 0;
while (fgets(line, sizeof (line), fp)) { //读取一行
++line_num; //下面的parse_line的实现是个状态机,本质上就是将没有意义的一行数据line转化为有意义的一个字符串数组p
if (parse_line (line, p, SIZE (p), file, line_num, msglevel, &options->gc)) {
bypass_doubledash (&p[0]); //越过"--"。下面的add_option将parse_line的结果--有意义的数组p填充到结构体option中,从而完成对配置文件一行的解析
add_option (options, p, file, line_num, level, msglevel, permission_mask, option_types_found, es);
}
}
fclose (fp);
}
上面的处理程序结构很紧凑,基本就是三件事情,1.读取一行;2.将一行无意义字符串转化为有意义的字符串数组;3.将有意义的字符串数组转化为程序内部结构体。除了诸如注释"#"需要处理之外(很简单,直接跳过),很少需要处理复杂的额外格式。如果说希望像处理命令行参数那样使用getopt_long处理参数,那么配置文件格式更简单,直接写成一行或者分行的情况在处理时删除换行符,然后将文件读入一个缓冲区,用awk处理该缓冲区,使之格式化成main参数argv[]的格式,最终传入getopt_long即可(man 3 getopt),非常灵活。正式因为配置文件写成--XXX yyy之类的格式可读性受到影响,因此才使用XXX yyy的格式,对于命令行,'-'或者'--'是可理解的最佳方式,但是对于配置文件,它们都不需要了,对比windows的ini文件,处理程序少了对[,],=等的解析。
windows为何采用ini“如此复杂”的文本格式,不得而知,但是unix的简单配置文件先入为主倒是不争的事实,即使windows中也有unix的影子,$WIN/system32/drivers/etc目录下面的文件hosts,networks,protocol等就是实例,即使是windows,在涉及网络配置的时候也还是使用unix的方式,这恰恰证明了网络从unix而来的事实(BSD和Sun的贡献很大)。既然很多网络配置业已成型,windows索性也要拿来主义了,这个只是猜测...windows其实也不是傻到了故意将配置文件复杂化,windows之所以采用基于section的配置文件可能是为了迎合其GUI,基于GUI的配置往往是具有结构的,最终的一个程序的配置就是一个树形的结构,比如“开始”菜单就是一个树形结构,而CLI程序的配置几乎都是线形结构,如果一个程序的配置是树形结构的话,采用线形的配置文件显然难于和GUI界面相对应,因此只能采用具有一定结构的配置文件,在这些结构化配置文件中,最简单的就是ini文件了,可见windows并不是不追求简单,而是它的GUI本身就将“简单”这个词的意义给异化了,在GUI的层次上,最简单的配置文件就是ini格式了,虽然并不是所有使用ini文件的程序都有GUI。这里说的GUI是一种思想而不仅仅指一个界面。
之所以说GUI臃肿是因为它没有做到单一的抽象,一个“按钮”除了具体的逻辑意义之外还有“视觉感官”意义,一个多级的菜单需要我们首先将它找出来才能使用,因此如何组织GUI结构就显得尤为重要,一个好的GUI程序必然需要组织良好的控件,反观CLI,只需要设计出配置参数即可,这些参数选项在命令行或者配置文件中的顺序并没有要求,设计上消除了“感官”需求,将所有的配置选项集中与单一的逻辑意义,因此才能使用最简单最高效的配置文件。CLI是外向的,GUI是内向的,其间的区别和字母文字之于汉字的区别一致。如果想在CLI程序中增加一个新的选项,只需两步即可,1.在程序内部结构体中增加一个字段;2.在解析参数时增加一个else if或者case,这种工作可以无限扩展,也就是说参数可以随意增加,最终只要完善一下手册,使用者就不会误用或者为不知参数何意而抓狂,另外CLI的使用者没有“寻找”参数位置的问题,使用一个选项参数之前,使用者必知道其意义(查阅手册),然后直接用键盘敲入即可。但是对于GUI程序来讲,增加一个选项必然牵扯到界面的变动,首先要考虑新的选项加在什么位置,那个菜单的哪个菜单项之下,随着选项的持续增多,菜单平铺则太长,子集过多则太深,使用控件之前必先找到该控件,总之查找的过程就是不便,最终控件的数量趋于可查找意义上的饱和,GUI在控件可查找性上已经不堪重负,再也不能增加控件了,GUI可扩展性受到“感官”限制,此谓内向。
GUI浪费了键盘上绝大多数按键,很多时候仅用鼠标即可,这在选项参数少的时候特别有用,比如回答“是”与“否”的案例,在GUI的情况下,用户一眼就可以看到写着“是”和“否”的控件,然后下鼠标点击即可,可是使用CLI的话,用户必须首先查阅手册,了解如果想选择“是”,因该输入什么...,面对着键盘上如此多的按键,真的不知道该按下哪些,但是如果只有两个按键,胡乱一按就可能成功,如果只有一个按键,那么就只有按它了,随着选项的增加,键盘被有效利用了,CLI的优势就体现出来了,最起码它使你不再觉得设计这么多按键是浪费了。选项越多,程序功能越复杂,越强大,而由于GUI有着天生的选项个数的限制,根本承担不了大任,除非放弃GUI,在windows上也写命令行程序。配置过IIS和Apache的应该对GUI和CLI的区别有所感受。
正是由于CLI程序使用键盘来配置而不是两击或者三击的鼠标,所以在CLI环境中才不提倡长文件名而几乎总用缩写,这是为了最少化输入(或许早期还起到了节省内存的作用),反观GUI,不管多长的文件名,点击即可,没有图标的情况下,文件名短了手一抖还不容易击中呢!最后GUI程序可以说没有真正配置的概念,它们几乎一开始就没有可扩展性,如果说CLI环境的程序是一台通用计算机,那么GUI程序则是一台已定制的带有固定按钮的电视机或者任意带有固定面板的机器。
从配置文件的格式扯到GUI和CLI
最新推荐文章于 2022-08-20 15:28:35 发布