zoukankan      html  css  js  c++  java
  • go-ini入门教程

    go-ini入门教程

    go-ini简介

    Package ini provides INI file read and write functionality in Go.

    在实际开发时,配置信息一般不会在代码里硬编码,通常是放在配置文件里,或者数据库、缓存里。今天介绍的 go-ini 就是一个读写 ini文件的库。

    配置文件格式有很多,常用的有 jsonxmlini。其中 ini 是以节(section)和键(key)构成,如下所示:

    #debug or release
    RUN_MODE = debug
    
    [app]
    PAGE_SIZE = 10
    

    快速使用

    1、下载安装

    使用一个特定版本:

    $ go get gopkg.in/ini.v1
    

    使用最新版本:

    $ go get github.com/go-ini/ini
    

    如需更新请添加 -u 选项。

    2、创建两个文件(my.inimain.go),这里选择放在 /home/ini-sample 目录。

    $ mkdir -p /home/ini-sample
    $ cd /home/ini-sample
    $ touch my.ini main.go
    $ tree .
    .
    ├── main.go
    └── my.ini
    
    0 directories, 2 files
    

    3、编译 my.ini 文件并输入以下内容:

    #debug or release
    RUN_MODE = debug
    
    [app]
    PAGE_SIZE = 10
    
    [server]
    HTTP_PORT = 8000
    READ_TIMEOUT = 60
    WRITE_TIMEOUT = 60
    
    [database]
    TYPE = mysql
    USER = 数据库账号
    PASSWORD = 数据库密码
    #127.0.0.1:3306
    HOST = 数据库IP:数据库端口号
    NAME = blog
    TABLE_PREFIX = blog_
    

    4、接着编写 main.go 文件来操作刚才创建的配置文件。

    package main
    import (
        "fmt"
        "os"
        "gopkg.in/ini.v1"
    )
    func main() {
        cfg, err := ini.Load("my.ini")
        if err != nil {
            fmt.Printf("Fail to read file: %v", err)
            os.Exit(1)
        }
        // 典型读取操作,默认分区可以使用空字符串表示
        fmt.Println("Run Mode:", cfg.Section("").Key("RUN_MODE").String())
        fmt.Println("Page Size:", cfg.Section("app").Key("PAGE_SIZE").String())
        // 试一试自动类型转换
        fmt.Printf("Http Port: (%[1]T) %[1]d
    ", cfg.Section("server").Key("HTTP_PORT").MustInt(9999))
        // 差不多了,修改某个值然后进行保存
        cfg.Section("").Key("RUN_MODE").SetValue("release")
        cfg.SaveTo("my.ini.local")
    }
    

    5、运行程序,可以看到以下输出:

    $ go run main.go
    Run Mode: debug
    Page Size: 10
    Http Port: (int) 8000
    
    $ cat my.ini.local 
    # debug or release
    RUN_MODE = release
    
    [app]
    PAGE_SIZE = 10
    
    [server]
    HTTP_PORT     = 8000
    READ_TIMEOUT  = 60
    WRITE_TIMEOUT = 60
    
    [database]
    TYPE         = mysql
    USER         = 数据库账号
    PASSWORD     = 数据库密码
    # 127.0.0.1:3306
    HOST         = 数据库IP:数据库端口号
    NAME         = blog
    TABLE_PREFIX = blog_
    

    操作分区(Section)

    获取指定分区:

    sec, err := cfg.GetSection("section name")
    

    如果想要获取默认分区,则可以用空字符串代替分区名:

    sec, err := cfg.GetSection("")
    

    操作键值(Value)

    获取一个类型为字符串(string)的值:

    val := cfg.Section("").Key("key name").String()
    

    Must*方法

    当我们知道配置的键值是哪种格式时,可以使用 Must* 方法来获取。

    v = cfg.Section("").Key("BOOL").MustBool()
    v = cfg.Section("").Key("FLOAT64").MustFloat64()
    v = cfg.Section("").Key("INT").MustInt()
    v = cfg.Section("").Key("INT64").MustInt64()
    v = cfg.Section("").Key("UINT").MustUint()
    v = cfg.Section("").Key("UINT64").MustUint64()
    v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339)
    v = cfg.Section("").Key("TIME").MustTime() // RFC3339
    // 由 Must 开头的方法名允许接收一个相同类型的参数来作为默认值,
    // 当键不存在或者转换失败时,则会直接返回该默认值。
    // 但是,MustString 方法必须传递一个默认值。
    v = cfg.Section("").Key("String").MustString("default")
    v = cfg.Section("").Key("BOOL").MustBool(true)
    v = cfg.Section("").Key("FLOAT64").MustFloat64(1.25)
    v = cfg.Section("").Key("INT").MustInt(10)
    v = cfg.Section("").Key("INT64").MustInt64(99)
    v = cfg.Section("").Key("UINT").MustUint(3)
    v = cfg.Section("").Key("UINT64").MustUint64(6)
    v = cfg.Section("").Key("TIME").MustTimeFormat(time.RFC3339, time.Now())
    v = cfg.Section("").Key("TIME").MustTime(time.Now()) // RFC3339
    

    In*方法

    获取键值时设定候选值,可以使用 In* 方法:

    v = cfg.Section("").Key("STRING").In("default", []string{"str", "arr", "types"})
    v = cfg.Section("").Key("FLOAT64").InFloat64(1.1, []float64{1.25, 2.5, 3.75})
    v = cfg.Section("").Key("INT").InInt(5, []int{10, 20, 30})
    v = cfg.Section("").Key("INT64").InInt64(10, []int64{10, 20, 30})
    v = cfg.Section("").Key("UINT").InUint(4, []int{3, 6, 9})
    v = cfg.Section("").Key("UINT64").InUint64(8, []int64{3, 6, 9})
    v = cfg.Section("").Key("TIME").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time1, time2, time3})
    v = cfg.Section("").Key("TIME").InTime(time.Now(), []time.Time{time1, time2, time3}) // RFC3339
    

    如果获取到的值不是候选值的任意一个,则会返回默认值,而默认值不需要是候选值中的一员。

    结构体与分区映射

    有时候我们不想逐个获取值,而是把分区内的值放到一个结构体里,以便使用。

    配置文件:

    #debug or release
    RUN_MODE = debug
    
    [app]
    PAGE_SIZE = 10
    
    [server]
    HTTP_PORT = 8000
    READ_TIMEOUT = 60
    WRITE_TIMEOUT = 60
    
    [database]
    TYPE = mysql
    USER = 数据库账号
    PASSWORD = 数据库密码
    #127.0.0.1:3306
    HOST = 数据库IP:数据库端口号
    NAME = blog
    TABLE_PREFIX = blog_
    

    代码:

    type Database struct {
    	Type string
    	User string
    	Password string
    	Host string
    	Name string
    	TablePrefix string
    }
    
    func Setup() {
    	Cfg, err := ini.Load("conf/app.ini")
    	if err != nil {
    		log.Fatalf("Fail to parse 'conf/app.ini': %v", err)
    	}
    
    	err = Cfg.Section("database").MapTo(DatabaseSetting)
    	if err != nil {
    		log.Fatalf("Cfg.MapTo DatabaseSetting err: %v", err)
    	}
    }
    

    使用心得

    通常配置文件很少变更的,一般使用单例,在 go 里就是包内变量了,由于只需要读取一次,所以一般会在 init 方法里读取。

    另外关于配置热更新,可以查看这份文章:热更新配置文件

    参考资料

  • 相关阅读:
    初识python: xlsxwriter 将数据写入Excel
    oracle 之 数组、嵌套表、SQL查询式 实现多表数据for循环插入指定表
    初识python:tkinter 实现 弹球小游戏(面向对象)
    初识python:tkinter 实现 弹球小游戏(非面相对象)
    初识python:scoket 单用户互发消息
    MagicNotes:如何迈向工作的坦途
    兴趣决定你成为什么样的人
    选择对了才去努力,努力了才能看到希望
    最健康的作息时间表与建议
    长期接受碎片化信息,会有什么后果?
  • 原文地址:https://www.cnblogs.com/liang24/p/14553583.html
Copyright © 2011-2022 走看看