当前位置:网站首页>Go learning --- read INI file
Go learning --- read INI file
2022-07-06 00:15:00 【Duck boss】
One 、 Read ini file
1、iniconfig Tool class
package iniConfig
import (
"errors"
"fmt"
"io/ioutil"
"reflect"
"strconv"
"strings"
)
func MarshalFile(filename string, data interface{}) (err error) {
result, err := Marshal(data)
if err != nil {
return
}
return ioutil.WriteFile(filename, result, 0755)
}
func Marshal(data interface{}) (result []byte, err error) {
typeInfo := reflect.TypeOf(data)
if typeInfo.Kind() != reflect.Struct {
err = errors.New("please pass struct")
return
}
var conf []string
valueInfo := reflect.ValueOf(data)
for i := 0; i < typeInfo.NumField(); i++ {
sectionField := typeInfo.Field(i)
sectionVal := valueInfo.Field(i)
fieldType := sectionField.Type
if fieldType.Kind() != reflect.Struct {
continue
}
tagVal := sectionField.Tag.Get("ini")
if len(tagVal) == 0 {
tagVal = sectionField.Name
}
section := fmt.Sprintf("\n[%s]\n", tagVal)
conf = append(conf, section)
for j := 0; j < fieldType.NumField(); j++ {
keyField := fieldType.Field(j)
fieldTagVal := keyField.Tag.Get("ini")
if len(fieldTagVal) == 0 {
fieldTagVal = keyField.Name
}
valField := sectionVal.Field(j)
item := fmt.Sprintf("%s=%v\n", fieldTagVal, valField.Interface())
conf = append(conf, item)
}
}
for _, val := range conf {
byteVal := []byte(val)
result = append(result, byteVal...)
}
return
}
func UnMarshalFile(filename string, result interface{}) (err error) {
data, err := ioutil.ReadFile(filename)
if err != nil {
return
}
return UnMarshal(data, result)
}
func UnMarshal(data []byte, result interface{}) (err error) {
lineArr := strings.Split(string(data), "\n")
typeInfo := reflect.TypeOf(result)
if typeInfo.Kind() != reflect.Ptr {
err = errors.New("please pass address")
return
}
typeStruct := typeInfo.Elem()
if typeStruct.Kind() != reflect.Struct {
err = errors.New("please pass struct")
return
}
var lastFieldName string
for index, line := range lineArr {
line = strings.TrimSpace(line)
if len(line) == 0 {
continue
}
// If it is a comment , Direct to ignore
if line[0] == ';' || line[0] == '#' {
continue
}
if line[0] == '[' {
lastFieldName, err = parseSection(line, typeStruct)
if err != nil {
err = fmt.Errorf("%v lineno:%d", err, index+1)
return
}
continue
}
err = parseItem(lastFieldName, line, result)
if err != nil {
err = fmt.Errorf("%v lineno:%d", err, index+1)
return
}
}
return
}
func parseItem(lastFieldName string, line string, result interface{}) (err error) {
index := strings.Index(line, "=")
if index == -1 {
err = fmt.Errorf("sytax error, line:%s", line)
return
}
key := strings.TrimSpace(line[0:index])
val := strings.TrimSpace(line[index+1:])
if len(key) == 0 {
err = fmt.Errorf("sytax error, line:%s", line)
return
}
resultValue := reflect.ValueOf(result)
sectionValue := resultValue.Elem().FieldByName(lastFieldName)
sectionType := sectionValue.Type()
if sectionType.Kind() != reflect.Struct {
err = fmt.Errorf("field:%s must be struct", lastFieldName)
return
}
keyFieldName := ""
for i := 0; i < sectionType.NumField(); i++ {
field := sectionType.Field(i)
tagVal := field.Tag.Get("ini")
if tagVal == key {
keyFieldName = field.Name
break
}
}
if len(keyFieldName) == 0 {
return
}
fieldValue := sectionValue.FieldByName(keyFieldName)
if fieldValue == reflect.ValueOf(nil) {
return
}
switch fieldValue.Type().Kind() {
case reflect.String:
fieldValue.SetString(val)
case reflect.Int8, reflect.Int16, reflect.Int, reflect.Int32, reflect.Int64:
intVal, errRet := strconv.ParseInt(val, 10, 64)
if errRet != nil {
err = errRet
return
}
fieldValue.SetInt(intVal)
case reflect.Uint8, reflect.Uint16, reflect.Uint, reflect.Uint32, reflect.Uint64:
intVal, errRet := strconv.ParseUint(val, 10, 64)
if errRet != nil {
err = errRet
return
}
fieldValue.SetUint(intVal)
case reflect.Float32, reflect.Float64:
floatVal, errRet := strconv.ParseFloat(val, 64)
if errRet != nil {
return
}
fieldValue.SetFloat(floatVal)
default:
err = fmt.Errorf("unsupport type:%v", fieldValue.Type().Kind())
}
return
}
func parseSection(line string, typeInfo reflect.Type) (fieldName string, err error) {
if line[0] == '[' && len(line) <= 2 {
err = fmt.Errorf("syntax error, invalid section:%s", line)
return
}
if line[0] == '[' && line[len(line)-1] != ']' {
err = fmt.Errorf("syntax error, invalid section:%s", line)
return
}
if line[0] == '[' && line[len(line)-1] == ']' {
sectionName := strings.TrimSpace(line[1 : len(line)-1])
if len(sectionName) == 0 {
err = fmt.Errorf("syntax error, invalid section:%s", line)
return
}
for i := 0; i < typeInfo.NumField(); i++ {
field := typeInfo.Field(i)
tagValue := field.Tag.Get("ini")
if tagValue == sectionName {
fieldName = field.Name
break
}
}
}
return
}
2、ini file
#this is comment
;this a comment
;[] It means a section
[server]
ip=10.238.2.2
port = 8080
[ mysql]
username =root
passwd = root
database=test
host=192.168.1.1
port=3838
timeout=1.23、 Read the file
package main
import (
"cal/iniConfig"
"fmt"
)
type Config struct {
ServerConf ServerConfig `ini:"server"`
MysqlConf MysqlConfig `ini:"mysql"`
}
type ServerConfig struct {
Ip string `ini:"ip"`
Port uint `ini:"port"`
}
type MysqlConfig struct {
Username string `ini:"username"`
Passwd string `ini:"passwd"`
Database string `ini:"database"`
Host string `ini:"host"`
Port int `ini:"port"`
Timeout float32 `ini:"timeout"`
}
func main() {
filename := "E:\\modeml\\cal\\reflect1\\1.ini"
var conf Config
err := iniConfig.UnMarshalFile(filename, &conf)
if err != nil {
fmt.Println("unmarshal failed,err:", err)
return
}
fmt.Printf("conf:%#v\n", conf)
}
边栏推荐
- Atcoder beginer contest 254 [VP record]
- Upgrade openssl-1.1.1p for openssl-1.0.2k
- Global and Chinese markets of POM plastic gears 2022-2028: Research Report on technology, participants, trends, market size and share
- LeetCode 6005. The minimum operand to make an array an alternating array
- Yunna | what are the main operating processes of the fixed assets management system
- 如何解决ecology9.0执行导入流程流程产生的问题
- Gavin teacher's perception of transformer live class - rasa project actual combat e-commerce retail customer service intelligent business dialogue robot system behavior analysis and project summary (4
- Senparc.Weixin.Sample.MP源码剖析
- PHP determines whether an array contains the value of another array
- 上门预约服务类的App功能详解
猜你喜欢

Key structure of ffmpeg -- AVCodecContext

教你在HbuilderX上使用模拟器运行uni-app,良心教学!!!

Configuring OSPF GR features for Huawei devices

There is no network after configuring the agent by capturing packets with Fiddler mobile phones

The difference of time zone and the time library of go language

Effet Doppler (déplacement de fréquence Doppler)

亲测可用fiddler手机抓包配置代理后没有网络

Single merchant v4.4 has the same original intention and strength!

云呐|固定资产管理系统主要操作流程有哪些

【二叉搜索树】增删改查功能代码实现
随机推荐
Huawei equipment is configured with OSPF and BFD linkage
Qt 一个简单的word文档编辑器
多普勒效應(多普勒頻移)
After summarizing more than 800 kubectl aliases, I'm no longer afraid that I can't remember commands!
第16章 OAuth2AuthorizationRequestRedirectWebFilter源码解析
【GYM 102832H】【模板】Combination Lock(二分图博弈)
Gd32f4xx UIP protocol stack migration record
The global and Chinese markets of dial indicator calipers 2022-2028: Research Report on technology, participants, trends, market size and share
NSSA area where OSPF is configured for Huawei equipment
How much do you know about the bank deposit business that software test engineers must know?
时区的区别及go语言的time库
FFmpeg学习——核心模块
Global and Chinese markets of POM plastic gears 2022-2028: Research Report on technology, participants, trends, market size and share
2022.7.5-----leetcode. seven hundred and twenty-nine
硬件及接口学习总结
数据库遇到的问题
【luogu P3295】萌萌哒(并查集)(倍增)
Solve the problem of reading Chinese garbled code in sqlserver connection database
Extracting profile data from profile measurement
【在线聊天】原来微信小程序也能回复Facebook主页消息!