Implementation of four file configuration methods in Golang

Keywords: Go

explain

In the actual development process, we are bound to use MySQL, Redis and other services. In order to realize the configuration of the system, we will put some configuration information in some files separately, and read the configuration file directly where we use it.

There are many common file configuration methods, such as json, tomal, yml or text format. Here are several ways to demonstrate one by one.

Demo code

JSON configuration

First, we create a JSON file to configure the parameter format we need, for example:

{
  "host": "127.0.0.1",
  "user": "root",
  "password": "123456",
  "port": "3306",
  "db": "demo"
}

To read the configuration file, we need to use the json package in Golang.

The specific reading process is as follows: read the content of json file - > use json package for deserialization - > use variables to store the data of deserialization.

// Use struct to define json format and storage.
type DbJson struct {
	Host     string `json:"host"`
	User     string `json:"user"`
	Password string `json:"password"`
	Port     string `json:"port"`
	Db       string `json:"db"`
}

// analysis
func GetJsonConfig() {
	// 1. Read json file content
	file, err := ioutil.ReadFile("./config/json.json")
	if err != nil {
		fmt.Println("err1", err)
		return
	}

	db := new(DbJson)
	// 2. Deserialize the read json file content; You will get a slice of type [] byte
	err = json.Unmarshal(file, db)
	if err != nil {
		fmt.Println("err2", err)
		return
	}
	// 2.1 deserialize the read json file content and copy it to map [string] [] byte (the same effect as in 2)
	allConfig := make(map[string]json.RawMessage, 0)
	err = json.Unmarshal(file, &allConfig)
	if err != nil {
		fmt.Println("err3", err)
		return
	}

	// 3. Loop map content
	for k, v := range allConfig {
		fmt.Println(k, string(v)) // If the value is of type [] byte, convert it to string
	}
}

Final input result:

host "127.0.0.1"
user "root"
password "123456"
port "3306"
db "demo"

In fact, both 2.1 and 2.1 are implemented in different ways.

yml configuration

yml format is also our common file configuration format. In Golang, we read the configuration mainly using gopkg.in/yaml.v2 package.

Similarly, we need to read the configuration file - > parse the contents of the file. Let's create a yml.yml file and write the following example configuration:

host: 127.0.0.1
user: root
password: 123456
port: 3306
db: demo

It should be noted that there is a space between the configuration item of yml and the value.

// Define a struct to define the format
type DbYml struct {
	Host     string `yaml:"host"`
	User     string `yaml:"user"`
	Password string `yaml:"password"`
	Port     string `yaml:"port"`
	Db       string `yaml:"db"`
}

func GetYmlConfig() {
	// 1. Read the content of the configuration file, and a [] byte content will be returned
	file, err := ioutil.ReadFile("./config/yml.yml")
	if err != nil {
		return
	}
	db := new(DbYml)

	// 2. Use yaml package for deserialization
	err = yaml.Unmarshal(file, db)
	if err != nil {
		return
	}
	fmt.Println(db.Host, db.User, db.Password, db.Port, db.Db)
}

Final input result:

127.0.0.1 root 123456 3306 demo

Text format

Reading the contents of the file format is to read by line, and then parse the contents of each line. Because the format in our text is generally the format of key=value in sequence, we just need to read the changed line and divide it according to =.

First, we create a file. txt with the following contents:

host=127.0.0.1
user=root
password=123456
port=3306
db=demo

Specific read configuration code:

func GetKeyValue() {
	allConfig := make(map[string]string)

	// 1. Read the file and get the file handle
	open, err := os.Open("./config/key.txt")
	if err != nil {
		fmt.Println("err1", err)
		return
	}

	// 2. Read file contents
	content := bufio.NewReader(open)
	for {
		// 3. Read file contents by line
		line, _, err := content.ReadLine()
		if err != nil {
			if err == io.EOF { // To read to the end, jump out of the loop
				break
			}
			return
		}
		// 4. Process the file contents read in each line
		s := strings2.TrimSpace(string(line)) // Remove the left and right spaces
		index := strings2.Index(s, "=")       // Because the configuration is =, the index location of = was found
		if index < 0 {
			continue
		}

		key := strings2.TrimSpace(s[:index]) // Intercept = the value on the left is key
		if len(key) == 0 {
			continue
		}

		value := strings2.TrimSpace(s[index+1:]) // Intercept = value on the right
		if len(value) == 0 {
			continue
		}

		allConfig[key] = value // Add to the map. Key is the key of the map and value is the value of the map
	}

	for k, v := range allConfig {
		fmt.Println(k, string(v))
	}

	defer open.Close() // Close closed file
}

The output is roughly as follows:

host 127.0.0.1
user root
password 123456
port 3306
db demo

tomal

The configuration file in toml format is mainly parsed by toml package. Similarly, first, we load the file and pass the path of the file into the toml package.

First, we create a toml file with the following definitions:

[database]
host="127.0.0.1"
user="root"
password="123456"
port=[3306, 3307]
db="demo"

The following is the specific parsing code:

import (
	"github.com/BurntSushi/toml"
	"path/filepath"
)

type DbToml struct {
	Db Database `toml:"database"`
}

type Database struct {
	Host     string
	User     string
	Password string
	Port     []int32
	Db       string
}

func GetToml() {
	// 1. Define structure variables to receive parsed data
	var config DbToml

	// 2. Obtain the absolute path of the file
	fileName, err := filepath.Abs("./config/toml.toml")
	if err != nil {
		fmt.Println("err1", err)
		return
	}

	// 3. Pass in the file path according to the rules of toml package
	_, err1 := toml.DecodeFile(fileName, &config)
	if err1 != nil {
		fmt.Println("err2", err1)
		return
	}

	fmt.Println(config.Db.Host, config.Db.User, config.Db.Password, config.Db.Port[0], config.Db.Db)
}

The output results are as follows:

127.0.0.1 root 123456 3306 demo

Posted by wildwobby on Fri, 03 Dec 2021 18:58:33 -0800