[golang]自己动手实现ini文件读取

来源:互联网 发布:python twisted下载 编辑:程序博客网 时间:2024/06/07 08:53

最近迷恋go语言,但我是个编程菜鸟,这个读取参考了beego的config,只是半成品,不过能够正常运行。

  1. 接口的设计
type Parser interface {Parse() error}type Config interface {GetString(string)stringParser}

目前只支持最小操作,解析和获取。在读取之前,要让config实例化一个对象:

var config Configfunc RegisterConfig(mode,path string){switch mode{case "ini":config=ini.NewIniConfig(path)case "json":case "xml":default:panic("Dosn't Supported configure type.")}}

这样,只要Iniconfig实现了config接口,就能将实例化的对象赋值给config,这个对象是全局的,外部调用config.Regi...之后,调用封装好的操做即可获取实例,实现功能。

全局实现:util.go

package configimport "mytools/config/ini"type Parser interface {Parse() error}type Config interface {GetString(string)stringParser}var config Configfunc RegisterConfig(mode,path string){switch mode{case "ini":config=ini.NewIniConfig(path)case "json":case "xml":default:panic("Dosn't Supported configure type.")}}func GetConfig()*Config{return &config}

IniConfig实现

package iniimport ("os""sync""bufio""io""bytes""strings""log")var(DEFAULT_SECTION stringCOMMENT []byteSEPARATOR []byte//SECTION_START string//SECTION_END string)//const(//LEFT = iota//RIGHT//)func init(){DEFAULT_SECTION="default"COMMENT=[]byte{'#'}SEPARATOR=[]byte{'='}}//type EntryConfig struct {//IsAlign bool //对齐//AlignType int //对齐类型//}type IniEntry struct {value interface {}}type IniConfig struct {filename stringsection map[string]*IniSectionsync.RWMutex}func NewIniConfig(path string) *IniConfig{config:=&IniConfig{path,make(map[string]*IniSection),sync.RWMutex{}}config.section[DEFAULT_SECTION]=NewIniSection()return config}func (c *IniConfig)Parse() error{file,err:=os.Open(c.filename)if err!=nil {return err}c.Lock()defer c.Unlock()defer file.Close()buf:=bufio.NewReader(file)section:=DEFAULT_SECTIONvar bufRead intfor{//读取一行缓存line,_,err:=buf.ReadLine()bufRead = bufRead + len(line)if err==io.EOF{//读到文件结尾,退出循环break}if bytes.Equal(line,[]byte("")){//空行直接跳过循环continue}//删除行两端的空白字符line=bytes.TrimSpace(line)if bytes.HasPrefix(line,COMMENT){//注释行暂时不做处理continue}if bytes.HasPrefix(line,[]byte("["))&&bytes.HasSuffix(line,[]byte("]")){//section处理//现在line确定为"[sectioname]"//不知道有没有合法性检查section=string(line[1:len(line)-1])section=strings.ToLower(section)if _,ok:=c.section[section];!ok{c.section[section]=NewIniSection()}}else{//key=value处理pair:= bytes.SplitN(line,SEPARATOR,2)key:= pair[0]val:=pair[1]if _,ok:=c.section[section];!ok{c.section[section]=NewIniSection()}log.Println(key,val)c.section[section].addEntry(string(key),string(val))}}return nil}func (c *IniConfig)RemoveSection(key string) error{return nil}func (c *IniConfig)GetString(k string) string{s:=strings.Split(k,":")var sec stringvar key stringif len(s)==1{sec=DEFAULT_SECTIONkey=s[0]log.Println(sec,key)}else{sec=s[0]key=s[1]log.Println(sec,key)}if v,ok:=c.section[sec].getEntry(key).(string);ok{return v}return ""}
首先看结构,Ini文件最基本的组成由注释,模块,项三个部分,其中,注释行可能由特定的字符开头,比如“#”,“;”等,现在默认是"#",如果要支持自定义字符,添加接口和check操作就能实现。在模块加载时我们就已经定义好了默认操作。参见init函数。
在回过头看看section,iniconfig是一个深度为2的树结构,每个树的跟节点是sectionname,子节点是配置项key=value,默认有一个defaultsection。
在解析方面,逐行读取,然后根据ini文件特点,处理注释行,注释段(未实现),section,和项,之后把他们转换成数据结构保存在Iniconfig中,只要调用GetString即可拿到配置项,语法为"section:key"。
那么,先到这里吧。

菜鸟轻喷。。。。。


                                             
0 0
原创粉丝点击