当前位置:网站首页>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)
}
边栏推荐
- 7.5 simulation summary
- 多普勒效應(多普勒頻移)
- JS can really prohibit constant modification this time!
- FFMPEG关键结构体——AVFormatContext
- Priority queue (heap)
- Global and Chinese markets for hinged watertight doors 2022-2028: Research Report on technology, participants, trends, market size and share
- Gd32f4xx UIP protocol stack migration record
- 选择致敬持续奋斗背后的精神——对话威尔价值观【第四期】
- [designmode] adapter pattern
- [online chat] the original wechat applet can also reply to Facebook homepage messages!
猜你喜欢

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

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

wx. Getlocation (object object) application method, latest version

FFMPEG关键结构体——AVFormatContext

Hardware and interface learning summary
![[day39 literature extensive reading] a Bayesian perspective on magnetic estimation](/img/9c/438ef820a9f703c21f708bfc1dbbc4.jpg)
[day39 literature extensive reading] a Bayesian perspective on magnetic estimation
![Choose to pay tribute to the spirit behind continuous struggle -- Dialogue will values [Issue 4]](/img/d8/a367c26b51d9dbaf53bf4fe2a13917.png)
Choose to pay tribute to the spirit behind continuous struggle -- Dialogue will values [Issue 4]

PV static creation and dynamic creation

wx.getLocation(Object object)申请方法,最新版
![N1 # if you work on a metauniverse product [metauniverse · interdisciplinary] Season 2 S2](/img/f3/8e237296f5948dd0488441aa625182.jpg)
N1 # if you work on a metauniverse product [metauniverse · interdisciplinary] Season 2 S2
随机推荐
openssl-1.0.2k版本升级openssl-1.1.1p
wx.getLocation(Object object)申请方法,最新版
What are Yunna's fixed asset management systems?
FFMPEG关键结构体——AVFrame
shardingsphere源码解析
Global and Chinese markets of universal milling machines 2022-2028: Research Report on technology, participants, trends, market size and share
【DesignMode】装饰者模式(Decorator pattern)
[gym 102832h] [template] combination lock (bipartite game)
USB Interface USB protocol
关于结构体所占内存大小知识
【DesignMode】组合模式(composite mode)
Hardware and interface learning summary
Transport layer protocol ----- UDP protocol
7.5 装饰器
跟着CTF-wiki学pwn——ret2libc1
教你在HbuilderX上使用模拟器运行uni-app,良心教学!!!
Knowledge about the memory size occupied by the structure
LeetCode 1598. Folder operation log collector
Yunna | what are the main operating processes of the fixed assets management system
数据库遇到的问题