直接上代码:

  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 }

go简单写个ini配置文件读取工具的更多相关文章

  1. (转载)将DELPHI数据库连接写进INI配置文件中

    将DELPHI数据库连接写进INI配置文件中 procedure TDM.DataModuleCreate(Sender: TObject); var piececonfg:Tinifile; pat ...

  2. 【代码】ini 文件读取工具类

    using System; using System.Runtime.InteropServices; using System.Text; namespace hrattendance.Common ...

  3. 配置文件读取工具类--PropertiesUtil

    /** * 属性工具类 * @author admin * 参考:https://www.cnblogs.com/doudouxiaoye/p/5693454.html */ public class ...

  4. Java读取Maven工程下的配置文件,工具类

    Java开发中,经常需要在maven工程中读取src/main/resources下的配置文件: 思路如下: Class.getClassLoader() 返回类加载器ClassLoader,进而可以 ...

  5. python 提供INI配置文件的操作 ConfigParser

    原文地址:http://www.cnblogs.com/pumaboyd/archive/2008/08/11/1265416.html 红色的为标注信息 +++++++++++++++++引用+++ ...

  6. C 构造一个 简单配置文件读取库

    前言 最近看到这篇文章, json引擎性能对比报告 http://www.oschina.net/news/61942/cpp-json-compare?utm_source=tuicool 感觉技术 ...

  7. 用C读取INI配置文件

    http://blog.csdn.net/chexlong/article/details/6818017 #define CONF_FILE_PATH "Config.ini" ...

  8. 转 python3 读取 ini配置文件

    在代码中经常会通过ini文件来配置一些常修改的配置.下面通过一个实例来看下如何写入.读取ini配置文件. 需要的配置文件是: 1 [path] 2 back_dir = /Users/abc/Pych ...

  9. 【Selenium05篇】python+selenium实现Web自动化:读取ini配置文件,元素封装,代码封装,异常处理,兼容多浏览器执行

    一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 这是python+selenium实现Web自动化第五篇博 ...

  10. Python读取ini配置文件的方式

    python configparser模块   ConfigParser模块在python中用来读取配置文件,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节(section ...

随机推荐

  1. 如何在es中查询null值

    目录 1.背景 2.需求 3.准备数据 3.1 创建mapping 3.2 插入数据 4.查询 name字段为null的数据 5.查询address不存在或值直接为null的数据 6.参考链接 1.背 ...

  2. 【原创】项目六 Load Of The Root

    实战流程 新创建文件夹,在这个文件夹里进行操作 nmap扫描下网段 根据nmap逐个排查,发现目标主机,但只有22端口 因此进一步扫描22端口的具体信息,没有扫出很有用的信息 发现靶场又提示一个用户, ...

  3. day04-视图和视图解析器

    视图和视图解析器 1.基本介绍 在SpringMVC中的目标方法,最终返回的都是一个视图(有各种视图) 注意,这里的视图是一个类对象,不是一个页面!! 返回的视图都会由一个视图解析器来处理(视图解析器 ...

  4. 12月6日内容总结——BOM、DOM、两者查找标签的方式和操作标签的方式、操作class和css的方法、事件、jQuery类库

    目录 一.BOM操作 BOM概念 window对象 window的子对象 navigator对象(了解即可) screen对象(了解即可) history对象(了解即可) location对象 弹出框 ...

  5. 10月27日内容总结——hashlib加密模块和logging、subprocess模块

    目录 一.hashlib加密模块 1.何为加密 2.为什么加密 3.如何判断数据是否以加密 4.密文的长短有什么意义 5.加密算法的基本操作 二.加密补充说明 三.subprocess模块 1.sub ...

  6. 基于遗传算法的地图四色原理绘图上色的Python代码

      本文介绍利用Python语言,实现基于遗传算法(GA)的地图四色原理着色操作. 1 任务需求   首先,我们来明确一下本文所需实现的需求.   现有一个由多个小图斑组成的矢量图层,如下图所示.   ...

  7. HOMER docker版本安装详细流程

    概述 HOMER是一款100%开源的针对SIP/VOIP/RTC的抓包工具和监控工具. HOMER是一款强大的.运营商级.可扩展的数据包和事件捕获系统,是基于HEP/EEP协议的VoIP/RTC监控应 ...

  8. 简单了解C语言如何构建多文件项目

    简单理解C语言如何构建工程 首先我们最好有一个好用的编辑器,vscode也好,visual studio也罢,dev也行,这里我们使用的是code::block: 一.了解C语言工程的构建原理 ​ 首 ...

  9. 用ChatGPT来了解ChatGPT

    用ChatGPT来了解ChatGPT 之前学习一个新技术, 想着要搞清楚这6个问题(来自陈皓介绍的学习方法): 1.这个技术出现的背景, 初衷, 要达到什么样的目标或是要解决什么样的问题. 2.这个技 ...

  10. 深度优先搜索算法-dfs讲解

    迷宫问题 有一个迷宫: S**. .... ***T (其中字符S表示起点,字符T表示终点,字符*表示墙壁,字符.表示平地.你需要从S出发走到T,每次只能向上下左右相邻的位置移动,不能走出地图,也不能 ...