• go简单写个ini配置文件读取工具


    直接上代码:

      1 package main
      2 
      3 import (
      4     "fmt"
      5     "io/ioutil"
      6     "reflect"
      7     "strconv"
      8     "strings"
      9 )
     10 
     11 type MysqlConfig struct {
     12     Address  string `ini:"address"`
     13     Port       int    `ini:"port"`
     14     UserName string `ini:"username"`
     15     PassWord string `ini:"password"`
     16 }
     17 
     18 type RedisConfig struct {
     19     Host      string `ini:"host"`
     20     Port      int    `ini:"port"`
     21     PassWord string `ini:"password"`
     22     DataBase int    `ini:"database"`
     23 }
     24 
     25 type Config struct {
     26     MysqlConfig `ini:"mysql"`
     27     RedisConfig `ini:"redis"`
     28 }
     29 
     30 func loadIni(fileName string, v interface{}) error {
     31     // 参数校验:v需为结构体指针类型
     32     t := reflect.TypeOf(v)
     33     if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
     34         return fmt.Errorf("v should be a struct ptr")
     35     }
     36 
     37     // 读取文件得到数据后立即关闭文件
     38     f, err := ioutil.ReadFile(fileName)
     39     if err != nil {
     40         return err
     41     }
     42     // 逐行获取文件内容,将值赋值给对应的结构体对象
     43     lineSlice := strings.Split(string(f), "\n")
     44     var structName string
     45     for index, line := range lineSlice {
     46         line = strings.TrimSpace(line)
     47         // 跳过注释和空行
     48         if strings.HasPrefix(line, ";") || strings.HasPrefix(line, "#") || len(line) == 0 {
     49             continue
     50         }
     51         // 以 [ 开头,为节点,需以 ] 结尾,且除空格外存在字符
     52         if strings.HasPrefix(line, "[") {
     53             if line[len(line) - 1] != ']' {
     54                 return fmt.Errorf("line:%d syntax error", index+1)
     55             }
     56             sectionName := strings.TrimSpace(line[1:len(line)-1])
     57             if len(sectionName) == 0 {
     58                 return fmt.Errorf("line:%d syntax error", index+1)
     59             }
     60             // 根据字符串sectionName去v里面根据反射找到对应的结构体
     61             for i :=0 ; i < t.Elem().NumField(); i ++ {
     62                 field := t.Elem().Field(i)
     63                 if sectionName == field.Tag.Get("ini") {
     64                     structName = field.Name
     65                     //fmt.Println(structName)
     66                     break
     67                 }
     68             }
     69         } else {
     70             // 不以 [ 开头,为以=分割的键值对
     71             if strings.Index(line, "=") == -1 || strings.HasPrefix(line, "=") {
     72                 return fmt.Errorf("line:%d syntax error", index+1)
     73             }
     74             // 根据struct名称找到对应结构体
     75             data := reflect.ValueOf(v)
     76             structValue := data.Elem().FieldByName(structName)  // 拿到嵌套结构体的值信息
     77             structType := structValue.Type()  // 拿到嵌套结构体的类型信息
     78             if structType.Kind() != reflect.Struct {
     79                 return fmt.Errorf("config struct field %s must be a struct", structName)
     80             }
     81             // 拆分键值对并赋值
     82             paramSlice := strings.Split(line, "=")
     83             key, value := strings.TrimSpace(paramSlice[0]), strings.TrimSpace(paramSlice[1])
     84             for x := 0; x < structType.NumField(); x ++ {
     85                 // 先拿到fieldType,fieldType中可以拿到field的值类型
     86                 fieldType := structType.Field(x)
     87                 if fieldType.Tag.Get("ini") == key {
     88                     // 根据field名称拿到field字段
     89                     fieldV := structValue.FieldByName(fieldType.Name)
     90                     // 给字段赋值
     91                     switch fieldType.Type.Kind() {
     92                     case reflect.String:
     93                         fieldV.SetString(value)
     94                     case reflect.Int,reflect.Int8,reflect.Int16,reflect.Int32,reflect.Int64:
     95                         valueInt, err := strconv.ParseInt(value, 10, 64)
     96                         if err != nil {
     97                             return fmt.Errorf("parseInt error, err:%v", err)
     98                         }
     99                         fieldV.SetInt(valueInt)
    100                     case reflect.Float32:
    101                         valueFloat, err := strconv.ParseFloat(value, 32)
    102                         if err != nil {
    103                             return fmt.Errorf("parseFloat error, err:%v", err)
    104                         }
    105                         fieldV.SetFloat(valueFloat)
    106                     case reflect.Float64:
    107                         valueFloat, err := strconv.ParseFloat(value, 64)
    108                         if err != nil {
    109                             return fmt.Errorf("parseFloat error, err:%v", err)
    110                         }
    111                         fieldV.SetFloat(valueFloat)
    112                     case reflect.Bool:
    113                         valueBool, err := strconv.ParseBool(value)
    114                         if err != nil {
    115                             return fmt.Errorf("parseBool error, err:%v", err)
    116                         }
    117                         fieldV.SetBool(valueBool)
    118                     }
    119                     break
    120                 }
    121             }
    122         }
    123     }
    124     return nil
    125 }
    126 
    127 func main() {
    128     var config Config
    129     fileName := "/home/xxx/data/demo_config/config.ini"
    130     err := loadIni(fileName, &config)
    131     if err != nil {
    132         fmt.Printf("load ini failed, err:%v", err)
    133     }
    134     fmt.Println("mysql config:")
    135     fmt.Printf("address:%s\tport:%d\tusername:%s\tpassword:%s\n", config.MysqlConfig.Address, config.MysqlConfig.Port, config.MysqlConfig.UserName, config.MysqlConfig.PassWord)
    136 
    137     fmt.Println("redis config:")
    138     fmt.Printf("host:%s\tport:%d\tpassword:%s\tdatabase:%d\n", config.RedisConfig.Host, config.RedisConfig.Port, config.RedisConfig.PassWord, config.RedisConfig.DataBase)
    139 }
  • 相关阅读:
    《Redis 设计与实现》读书笔记(四)
    《Redis 设计与实现》读书笔记(三)
    《Redis 设计与实现》读书笔记(二)
    《Redis 设计与实现》读书笔记(一)
    《Mysql技术内幕-InnoDB存储引擎》读书笔记 (一)
    Python调试工具
    记一次偶发的bug排查——redis-py-cluster库的bug
    苹果支付的这些漏洞,你都堵上了吗?
    微软消息队列-MicroSoft Message Queue(MSMQ)队列的C#使用
    Quartz.net设置任务中同时最多运行一个实例 [DisallowConcurrentExecution]
  • 原文地址:https://www.cnblogs.com/zzmx0/p/15612603.html
Copyright © 2020-2023  润新知