当前位置:网站首页>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)
}
边栏推荐
- Global and Chinese market of digital serial inverter 2022-2028: Research Report on technology, participants, trends, market size and share
- Choose to pay tribute to the spirit behind continuous struggle -- Dialogue will values [Issue 4]
- DEJA_ Vu3d - cesium feature set 055 - summary description of map service addresses of domestic and foreign manufacturers
- Effet Doppler (déplacement de fréquence Doppler)
- What if the C disk is not enough? Let's see how I can clean up 25g of temp disk space after I haven't redone the system for 4 years?
- 选择致敬持续奋斗背后的精神——对话威尔价值观【第四期】
- OS i/o devices and device controllers
- Initialize your vector & initializer with a list_ List introduction
- Yunna | what are the main operating processes of the fixed assets management system
- [QT] QT uses qjson to generate JSON files and save them
猜你喜欢
AtCoder Beginner Contest 258【比赛记录】
AtCoder Beginner Contest 254【VP记录】
China Jinmao online electronic signature, accelerating the digitization of real estate business
N1 # if you work on a metauniverse product [metauniverse · interdisciplinary] Season 2 S2
Doppler effect (Doppler shift)
云呐|公司固定资产管理系统有哪些?
【DesignMode】组合模式(composite mode)
时区的区别及go语言的time库
PV static creation and dynamic creation
XML配置文件(DTD详细讲解)
随机推荐
LeetCode 8. String conversion integer (ATOI)
[Luogu cf487e] tours (square tree) (tree chain dissection) (line segment tree)
What is information security? What is included? What is the difference with network security?
Solve the problem of reading Chinese garbled code in sqlserver connection database
FFT 学习笔记(自认为详细)
[noi simulation] Anaid's tree (Mobius inversion, exponential generating function, Ehrlich sieve, virtual tree)
Qt 一个简单的word文档编辑器
shardingsphere源码解析
Global and Chinese market of valve institutions 2022-2028: Research Report on technology, participants, trends, market size and share
Hudi of data Lake (1): introduction to Hudi
QT--线程
亲测可用fiddler手机抓包配置代理后没有网络
18. (ArcGIS API for JS) ArcGIS API for JS point collection (sketchviewmodel)
FFmpeg学习——核心模块
2022.7.5-----leetcode.729
【luogu CF487E】Tourists(圆方树)(树链剖分)(线段树)
Start from the bottom structure and learn the introduction of fpga---fifo IP core and its key parameters
什么叫做信息安全?包含哪些内容?与网络安全有什么区别?
[binary search tree] add, delete, modify and query function code implementation
Open3D 点云随机添加噪声