golang 配置文件读取与写入

toolvcn · 2022-01-15 10:52:24 · 940 次点击 · 预计阅读时间 3 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2022-01-15 10:52:24 的文章,其中的信息可能已经有所发展或是发生改变。

配置文件的读取与解析 config.json

没有配置则读取默认配置

结构体读取,初学者demo,有啥问题可以留言交流

package main

import (
    "encoding/json"
    "errors"
    "fmt"
    "io/ioutil"
    "os"
    "reflect"
    "strconv"
)

type ConfigStruct struct {
    A string `json:"A" default:"a"`
    B int    `json:"B" default:"1"`
    G struct {
        AA string `json:"AA" default:"aa"`
        BB int    `json:"BB" default:"22"`
        GG struct {
            AAA string `json:"AAA" default:"aaa"`
            BBB int    `json:"BBB" default:"333"`
            // ...struct
        }
    }
}

type ConfigInterface interface {
    // 恢复默认值
    ReDefault(config *interface{}) error
    // 读取配置文件
    ReadFile() error
    // 写入配置文件
    WriteFile() error
}

// 配置
var Config ConfigStruct

// 配置文件名
var configFile string = "config.json"

// 默认值标签名
var tagDefaultName string = "default"

// 恢复默认值
func (Config *ConfigStruct) ReDefault(config interface{}) error {
    t, v := reflect.TypeOf(config), reflect.ValueOf(config)
    tE, vE := t.Elem(), v.Elem()
    if t.Kind() != reflect.Ptr || v.Kind() != reflect.Ptr {
        return errors.New("参数必须是指针")
    }
    if tE.Kind() != reflect.Struct || vE.Kind() != reflect.Struct {
        return errors.New("参数元素必须是结构体")
    }
    for i := 0; i < tE.NumField(); i++ {
        tEf, vEf := tE.Field(i), vE.Field(i)
        tagV := tEf.Tag.Get(tagDefaultName)
        switch vEf.Kind() {
        case reflect.Struct:
            if err := Config.ReDefault(vEf.Addr().Interface()); err != nil {
                return err
            }
        case reflect.String:
            if len(tagV) > 0 {
                vEf.SetString(tagV)
            }
        case reflect.Int:
            if len(tagV) > 0 {
                number, err := strconv.ParseInt(tagV, 0, 64)
                if err == nil {
                    vEf.SetInt(number)
                } else {
                    return err
                }
            }
        default:
            return errors.New("不能处理类型 " + vEf.Kind().String())
        }
    }
    return nil
}

// 读取配置文件
func (Config *ConfigStruct) ReadFile() error {
    configFile, err := ioutil.ReadFile(configFile)
    if err != nil {
        return err
    }
    if err2 := json.Unmarshal(configFile, Config); err2 != nil {
        return err
    }
    return nil
}

// 写入配置文件
func (Config *ConfigStruct) WriteFile() error {
    jsonStr, err := json.MarshalIndent(Config, "", "\t")
    if err != nil {
        return err
    }
    if err := ioutil.WriteFile(configFile, jsonStr, os.ModePerm); err != nil {
        return err
    }
    return nil
}

func init() {
    if err := Config.ReadFile(); err == nil {
        fmt.Println("读取配置文件成功")
    } else {
        fmt.Println("读取配置文件失败", err)
        if err := Config.ReDefault(&Config); err == nil {
            fmt.Println("恢复默认参数成功")
            if err := Config.WriteFile(); err == nil {
                fmt.Println("生成配置文件成功")
            } else {
                fmt.Println("生成配置文件失败", err)
            }
        } else {
            fmt.Println("恢复默认参数失败", err)
        }
    }
}

func main() {
    jsonStr, _ := json.Marshal(Config)
    fmt.Printf("%s \n", jsonStr)
}

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

940 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传