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 }
go简单写个ini配置文件读取工具的更多相关文章
- (转载)将DELPHI数据库连接写进INI配置文件中
将DELPHI数据库连接写进INI配置文件中 procedure TDM.DataModuleCreate(Sender: TObject); var piececonfg:Tinifile; pat ...
- 【代码】ini 文件读取工具类
using System; using System.Runtime.InteropServices; using System.Text; namespace hrattendance.Common ...
- 配置文件读取工具类--PropertiesUtil
/** * 属性工具类 * @author admin * 参考:https://www.cnblogs.com/doudouxiaoye/p/5693454.html */ public class ...
- Java读取Maven工程下的配置文件,工具类
Java开发中,经常需要在maven工程中读取src/main/resources下的配置文件: 思路如下: Class.getClassLoader() 返回类加载器ClassLoader,进而可以 ...
- python 提供INI配置文件的操作 ConfigParser
原文地址:http://www.cnblogs.com/pumaboyd/archive/2008/08/11/1265416.html 红色的为标注信息 +++++++++++++++++引用+++ ...
- C 构造一个 简单配置文件读取库
前言 最近看到这篇文章, json引擎性能对比报告 http://www.oschina.net/news/61942/cpp-json-compare?utm_source=tuicool 感觉技术 ...
- 用C读取INI配置文件
http://blog.csdn.net/chexlong/article/details/6818017 #define CONF_FILE_PATH "Config.ini" ...
- 转 python3 读取 ini配置文件
在代码中经常会通过ini文件来配置一些常修改的配置.下面通过一个实例来看下如何写入.读取ini配置文件. 需要的配置文件是: 1 [path] 2 back_dir = /Users/abc/Pych ...
- 【Selenium05篇】python+selenium实现Web自动化:读取ini配置文件,元素封装,代码封装,异常处理,兼容多浏览器执行
一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 这是python+selenium实现Web自动化第五篇博 ...
- Python读取ini配置文件的方式
python configparser模块 ConfigParser模块在python中用来读取配置文件,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节(section ...
随机推荐
- 小白从零到AIoT之路(前言)
什么是AIoT 简单来说就是AI(人工智能)+IoT(物联网)= AIoT(人工智能物联网). AIoT融合AI技术和IoT技术,通过物联网产生.收集来自不同维度的.海量的数据存储于云端.边缘端,再通 ...
- ASP.NET Core - IStartupFilter 与 IHostingStartup
1. IStartupFilter 上面讲到的方式虽然能够根据不同环境将Startup中的启动逻辑进行分离,但是有些时候我们还会可以根据应用中的功能点将将一系列相关中间件的注册封装到一起,从 St ...
- ubuntu 备份系统
1.安装Systemback: sudo add-apt-repository ppa:nemh/systemback sudo apt-get update sudo apt-get install ...
- ES6的Promise用法
一.是什么: promise是异步编程的一种解决方案,它是一个对象,可以获取异步操作的信息,它的出现改善了异步编程,避免了地狱回调,它比传统的解决方案回调函数和事件更合理和更强大 二.promise的 ...
- yaml文件详解
一.yaml文件详解 前言 Kubernetes 支持 YAML 和 JSON 格式管理资源对象JSON 格式:主要用于 api 接口之间消息的传递YAML 格式:用于配置和管理,YAML 是一种简洁 ...
- H3C MS4300V2配置mac地址与接口绑定
配置mac地址与接口绑定 例: <h3c>system-view //进入系统视图 [h3c]int g 1/0/45 //进入45接口 [h3c-GigabitEthernet1 ...
- JZOJ 4319. 【NOIP2015模拟11.5】Lucas的数列
题目 思路 暴力很好打,我们显然可以先把关于 \(k\) 的式子拆开 先二项式展开,然后把外面的 \(m\) 乘进去,把 \(p\) 的分母 \(m\) 消去 \(K = (\sum_{i=1}^m ...
- [EULAR文摘] TNFi治疗3年对384例强柱患者脊柱放射学进展的影响
TNF拮抗剂治疗3年对384例强直性脊柱炎患者脊柱放射学进展的影响 Maksymowych WP, et al. EULAR 2015. Present ID: OP0144. 背景: 既往开放标签的 ...
- C# 数字转大写汉字
1.数字转换成汉字大写public string NumToChinese(string x) { //数字转换为中文后的数组 string[] P_array_num = new string[] ...
- Linux内存占用过高排查过程
1 查看服务器状态 系统是 CentOS Linux release 7.5.1804 (Core)使用top命令看了下系统的状态 系统的整体负载和cpu并不高,但是内存使用比较高(总8G使用了7.2 ...