当前位置:网站首页>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)
}
边栏推荐
- AtCoder Beginner Contest 258【比赛记录】
- What are the functions of Yunna fixed assets management system?
- 选择致敬持续奋斗背后的精神——对话威尔价值观【第四期】
- N1 # if you work on a metauniverse product [metauniverse · interdisciplinary] Season 2 S2
- Global and Chinese markets for hinged watertight doors 2022-2028: Research Report on technology, participants, trends, market size and share
- Wechat applet -- wxml template syntax (with notes)
- 7.5 decorator
- GD32F4xx uIP协议栈移植记录
- 转:未来,这样的组织才能扛住风险
- [binary search tree] add, delete, modify and query function code implementation
猜你喜欢
There is no network after configuring the agent by capturing packets with Fiddler mobile phones
Transport layer protocol ----- UDP protocol
剖面测量之提取剖面数据
Extracting profile data from profile measurement
XML配置文件(DTD详细讲解)
Learn PWN from CTF wiki - ret2libc1
FFMPEG关键结构体——AVFrame
About the slmgr command
18.(arcgis api for js篇)arcgis api for js点采集(SketchViewModel)
FFMPEG关键结构体——AVCodecContext
随机推荐
[designmode] adapter pattern
[Luogu cf487e] tours (square tree) (tree chain dissection) (line segment tree)
【luogu P3295】萌萌哒(并查集)(倍增)
用列錶初始化你的vector&&initializer_list簡介
GD32F4xx uIP协议栈移植记录
Priority queue (heap)
7.5模拟赛总结
云呐|公司固定资产管理系统有哪些?
[day39 literature extensive reading] a Bayesian perspective on magnetic estimation
Yunna | what are the main operating processes of the fixed assets management system
FFT learning notes (I think it is detailed)
软件测试工程师必会的银行存款业务,你了解多少?
微信小程序---WXML 模板语法(附带笔记文档)
CloudCompare&PCL 点云随机添加噪声
LeetCode 6005. The minimum operand to make an array an alternating array
MySql——CRUD
Problems encountered in the database
Hardware and interface learning summary
Tools to improve work efficiency: the idea of SQL batch generation tools
18. (ArcGIS API for JS) ArcGIS API for JS point collection (sketchviewmodel)