当前位置:网站首页>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.2
3、 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)
}
边栏推荐
- JS can really prohibit constant modification this time!
- 认识提取与显示梅尔谱图的小实验(观察不同y_axis和x_axis的区别)
- Global and Chinese market of water heater expansion tank 2022-2028: Research Report on technology, participants, trends, market size and share
- Global and Chinese markets for pressure and temperature sensors 2022-2028: Research Report on technology, participants, trends, market size and share
- NSSA area where OSPF is configured for Huawei equipment
- Doppler effect (Doppler shift)
- Problems encountered in the database
- Configuring OSPF GR features for Huawei devices
- MySql——CRUD
- 关于结构体所占内存大小知识
猜你喜欢
[designmode] Decorator Pattern
Laser slam learning record
云呐|固定资产管理系统功能包括哪些?
Open source CRM customer relationship system management system source code, free sharing
N1 # if you work on a metauniverse product [metauniverse · interdisciplinary] Season 2 S2
Initialiser votre vecteur & initialisateur avec une liste Introduction à la Liste
Yunna | what are the main operating processes of the fixed assets management system
Huawei equipment is configured with OSPF and BFD linkage
用列錶初始化你的vector&&initializer_list簡介
QT QPushButton details
随机推荐
LeetCode 8. String conversion integer (ATOI)
How much do you know about the bank deposit business that software test engineers must know?
FFMPEG关键结构体——AVFrame
Configuring OSPF GR features for Huawei devices
Redis high availability - master-slave replication, sentinel mode, cluster
After summarizing more than 800 kubectl aliases, I'm no longer afraid that I can't remember commands!
LeetCode 6004. Get operands of 0
7.5模拟赛总结
Detailed explanation of APP functions of door-to-door appointment service
[Luogu cf487e] tours (square tree) (tree chain dissection) (line segment tree)
Global and Chinese market of valve institutions 2022-2028: Research Report on technology, participants, trends, market size and share
Initialiser votre vecteur & initialisateur avec une liste Introduction à la Liste
云呐|固定资产管理系统功能包括哪些?
7.5 decorator
Global and Chinese markets for hinged watertight doors 2022-2028: Research Report on technology, participants, trends, market size and share
Atcoder beginer contest 254 [VP record]
Hudi of data Lake (1): introduction to Hudi
云呐|固定资产管理系统主要操作流程有哪些
Start from the bottom structure and learn the introduction of fpga---fifo IP core and its key parameters
【DesignMode】组合模式(composite mode)