Chinaunix首页 | 论坛 | 博客
  • 博客访问: 262650
  • 博文数量: 42
  • 博客积分: 2415
  • 博客等级: 大尉
  • 技术积分: 590
  • 用 户 组: 普通用户
  • 注册时间: 2006-01-13 14:14
文章分类

全部博文(42)

文章存档

2018年(1)

2017年(8)

2015年(3)

2012年(4)

2011年(11)

2010年(1)

2009年(5)

2008年(9)

我的朋友

分类: 云计算

2017-03-19 19:08:52

  配置分两部分,系统启动参数使用文件,业务参数使用NoSQL类的内存数据库,这里只讨论文件,数据库留到将来再说;
  使用json而不是ini格式的配置文件;
  对配置文件的解析不需要考虑内容,只要格式正确即可,需要配置的模块自行获取需要的字段。
  首先需要获取配置文件路径,考虑两种方式:1.命令行参数提供;2.命令行参数没有提供时使用缺省文件。
  1. var profile string
  2. flag.StringVar(&profile, "profile", os.Getenv("GOETC")+"/profile.json", "Full path of the profile.")
  3. flag.Parse()
  当然需要首先包含flag包和os包。
  os包是平台独立的操作系统接口,比方说上面的Getenv,linux对应的就是getenv,可以看到参数是一致的。$GOETC在.bash_profile里面定义。说到这里,其实也可以把许多启动参数放到.bash_profile里面,不过这只是一种选择,就不讨论了。
  flag包是专门用来解析命令行参数的。就StringVar函数来说,第一个参数用来保存读入的命令行参数,第二个参数是这个命令行参数的名字,第三个参数是缺省值,第四个参数是所谓的usage。
  以上面程序为例,假设命令行参数为 -profile=./profile.json,那么变量profile在函数返回之后就是“./profile.json"这么个字符串,如果我们启动程序时命令行没有profile这么一项,则变量profile的值将会是$GOETC/profile.json。
  我们可以用-h来获取所谓的usage,在这个程序里将打印的是
  1. Usage of mytchSever:
  2. -profile string
  3. Full path of the profile. (default "/home/whg/work/etc/profile.json")
  设定配置文件内容是个json格式的文本文档,用#或者;开头的行为注释:

点击(此处)折叠或打开

  1. {
  2. #no comments
  3.     "tcpPort":12345,
  4.     "httpPort":8080,
  5.     "httpsPort":436,
  6.     "others":{
  7.         "item1":"string",
  8.         "item2":false
  9.     }
  10. }
  获取配置文件全路径之后,就可以打开并读取内容了。
  1.     profileFD, err := os.Open(profile)
  2.     if err != nil {
  3.         panic(err)
  4.     }
  5.     defer profileFD.Close()

  6.     buffer := bufio.NewReader(profileFD)
  7.     var profileLines string
  8.     for {
  9.         line, err := buffer.ReadString('\n')
  10.         if err == io.EOF {
  11.             break
  12.         } else if line[0] == '#' || line[0] == ';' {
  13.             continue
  14.         } else if err != nil {
                panic(err)
            }
            profileLines+= line
  15.     }
  需要包含io和bufio包。当然操作文件不仅仅只有bufio这种方式,既然是文本,按行读取终究是要简单些,况且,程序效率并不在于读取配置文件的方式上。
  说到这,需要说明下strings.Trim系列函数,刚开始以为是直接修改原字符串,看文档才发现结果是通过返回值返回的。
  接下来,就是解析这个已经读出来的json串:
  1. var ProfileItems map[string]interface{} //全局变量

  1.     jsonLines := []byte(profileLines)

  2.     if err := json.Unmarshal(jsonLines, &ProfileItems); err != nil {
  3.         panic(err)
  4.     }
  5.     httpPort := ProfileItems["httpPort"].(float64)
  6.     httpsPort := ProfileItems["httpsPort"].(float64)
  7.     tcpPort := ProfileItems["tcpPort"].(float64)
  8.     others := ProfileItems["others"].(map[string]interface{})
  9.     item1 := others["item1"].(string)
  10.     item2 := others["item2"].(bool)
  需要注意的一个是jsonLines是个用profileLines初始化的slice,另外一个是others域的处理,当然也都是很直白的处理。
  这是到目前为止的全部代码:

点击(此处)折叠或打开

  1. package main

  2. import (
  3.     "bufio"
  4.     "encoding/json"
  5.     "flag"
  6.     "fmt"
  7.     "io"
  8.     "os"
  9.     // "strings"
  10.     //"unicode/utf8"
  11. )

  12. var ProfileItems map[string]interface{} //obviously,this var will be used in many files

  13. func main() {

  14.     var profile string
  15.     flag.StringVar(&profile, "profile", os.Getenv("GOETC")+"/profile.json", "Full path of the profile.")
  16.     flag.Parse()
  17.    
  18.     profileFD, err := os.Open(profile)
  19.     if err != nil {
  20.         panic(err)
  21.     }
  22.     defer profileFD.Close()

  23.     buffer := bufio.NewReader(profileFD)
  24.     var profileLines string
  25.     for {
  26.         line, err := buffer.ReadString('\n')
  27.         if err == io.EOF {
  28.             break
  29.         } else if line[0] == '#' || line[0] == ';' {
  30.             continue
  31.         } else if err != nil {
  32.             panic(err)
  33.         }

  34.         profileLines += line
  35.   }

  36.     jsonLines := []byte(profileLines)

  37.     if err := json.Unmarshal(jsonLines, &ProfileItems); err != nil {
  38.         panic(err)
  39.     }
  40. }




阅读(2114) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~