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 ...
随机推荐
- Random概述和基本使用-Random生成指定范围的随机数
Random概述和基本使用 什么是Random类 此类的实例用于生成伪随机数. 例如,以下代码使用户能够得到一个随机数: Random r = new Random(); int i = r.next ...
- wixtoolset visualstudio 2017打包流程(1)
第一步: 使用wix提供的 heat.exe 工具生成后缀为 wsx 的配置文件. heat.exe dir ".\binr" -dr INSTALLFOLDER -cg Pr ...
- 一文详解数仓GaussDB(DWS) 函数出参带出方式
摘要:本文主要讲解DWS函数出参带出方式. 本文分享自华为云社区<GaussDB(DWS)功能 -- 函数出参 #[玩转PB级数仓GaussDB(DWS)]>,作者:譡里个檔 . DWS的 ...
- ASP.NET Core 系列总结
<ASP.NET Core> 系列文章基于 .NET 3.1 和 .NET 6,主要是系统总结自己日常工作和学习中的知识点,之前是自己在 OneNote 上自己写,作为学习.总结笔记,逐渐 ...
- JavaScript的闭包和作用域
作用域相关 作用域的概念: 作用域是在运行时代码中的某些特定部分中变量,函数和对象的可访问性.换句话说,作用域决定了代码区块中变量和其他资源的可见性: 作用域的类型: 全局作用域: 最外层函数和在最外 ...
- cs 起源 fps 逆向
1.找到人物坐标X YZ2.找到鼠标X Y3.易语言读取人物坐标4.读取敌人坐标打开控制台服务器与客户端尽量找客户端 找到XYZ5.实时读取敌人坐标6.三角函数转换屏幕坐标FOV 视场角狙击枪找FOV ...
- 点击获取Cesium中加载的3DTile模型的属性信息(二)
1.添加鼠标点击事件 //鼠标单击左键事件 viewer.screenSpaceEventHandler.setInputAction(function onMouseClick( click ) { ...
- noip2020模拟赛 背包 (knapsack)
题目 区间 \(01\) 背包 \(1 \le l_i \le r_i \le n \le 20000,1 \le q \le 100000,1 \le m_i \le 500, 1 \le w_i ...
- 题解 P1627 [CQOI2009] 中位数
傻逼题但是被自己的傻逼操作爆了好几次零(悲愤 .... 没什么好讲的,一眼题... //SIXIANG #include <iostream> #define int long long ...
- 通过 Blob 创建下载文件
Blob 如上图所示,Blob 对象有三个部分组成,data:image/jpeg 表示该 Blob 是什么类型的文件.base64 是一个二进制到文本的编码,更多细节查看Base64 编码/解码.其 ...