iGO實現之路 —— Config
本文為轉載,原文:iGO實現之路 —— Config
介紹
相信大多數的程式設計師在使用各種框架開發的時候,都會有一個配置檔案讓我們做一些配置,比如說資料庫的配置,快取的配置,除錯的配置等等,這些配置只要我們填寫之後就會生效。
今天,我就用go語言實現是個讀取配置檔案的小模組。可能並不是非常的完成,或者還會存在一些不安全的因素。這裡我將我的實現寫出來,望發現問題的同學們提出來,我們大家共同進步。
原始碼地址
實現
config 模組的檔案列表如下圖所示:
-
conf
目錄為功能模組 example
目錄為測試程式碼
功能實現
config.go
由於我們的配置檔案型別可能是多種多樣的,比如ini,json等。所以,我首先得做一個Config的介面:
type Config interface{
GetString(string) string
GetInt(string)(int, error)
GetInt64(string)(int64, error)
GetFloat(string)(float64, error)
GetBool(string)(bool, error)
}
從程式碼中看,我們的介面比較簡單,就是一些從配置檔案中讀取各種型別的值,這裡先暫時支援string,int,int64,float,bool型別的資料讀取,後續如有需要再更新。
有了介面,就便於我們同意操作了。下面我們再做一個例項化的函式,這個就有點型別簡單工廠模式了。根據引數建立不同型別的例項:
func NewConfig(adapter, filename string) (Config, error){
path, err := GetCurrentPath(filename)
if err != nil{
return nil, err
}
switch adapter{
case "ini":
return GetIniConfig(path)
default:
return nil, errors.New("系統暫未處理該型別的配置檔案")
}
}
該函式有2個引數,adapter為我們適配的配置檔案型別,如ini, json等。filename為我們的配置檔案的相對路徑。 程式碼通過不同的adapter返回不同的例項。該函式中呼叫了個GetCurrentPath函式。
下面,我們看下GetCurrentPath函式的實現:
func GetCurrentPath(filename string) (path string, err error ){
path, err = filepath.Abs(filename)
if err != nil {
return
}
path = strings.Replace(path, "\\", "/", -1)
path = strings.Replace(path, "\\\\", "/", -1)
return
}
該函式的作用是將配置檔案的相對路徑轉換為絕對路徑。 至此,我們的公用的程式碼已經完成了。接下來就是各種不同的配置檔案的實現了,也就是各種對於Config介面實現的方案。
完整的config.go程式碼如下:
package conf
import (
"strings"
"errors"
"path/filepath"
)
type Config interface{
GetString(string) string
GetInt(string)(int, error)
GetInt64(string)(int64, error)
GetFloat(string)(float64, error)
GetBool(string)(bool, error)
}
func NewConfig(adapter, filename string) (Config, error){
path, err := GetCurrentPath(filename)
if err != nil{
return nil, err
}
switch adapter{
case "ini":
return GetIniConfig(path)
default:
return nil, errors.New("系統暫未處理該型別的配置檔案")
}
}
func GetCurrentPath(filename string) (path string, err error ){
path, err = filepath.Abs(filename)
if err != nil {
return
}
path = strings.Replace(path, "\\", "/", -1)
path = strings.Replace(path, "\\\\", "/", -1)
return
}
ini
ini_config.go
INI檔案格式是某些平臺或軟體上的配置檔案的非正式標準,以節(section)和鍵(key)構成,常用於微軟Windows作業系統中。這種配置檔案的副檔名多為INI,故名。
INI是英文“初始化”(initialization)的縮寫。正如該術語所表示的,INI檔案被用來對作業系統或特定程式初始化或進行引數設定。
既然知道了ini檔案,那麼我們就看看怎麼去讀取其配置吧。 先看下對於IniConfig的結構體定義:
type IniConfig struct{
ConfigMap map[string]string
strcet string
}
從config.go程式碼檔案中的NewConfig函式中,我們看到了這樣一個函式GetIniConfig
,而該函式就是對於ini檔案配置的初始化:
func GetIniConfig(filename string)(*IniConfig, error){
middle := "."
config := new(IniConfig)
config.ConfigMap = make(map[string]string)
//開啟檔案
file, err := os.Open(filename)
if err != nil{
return nil, err
}
defer file.Close()
read := bufio.NewReader(file)
for{
b, _, err := read.ReadLine()
if err != nil {
if err == io.EOF{
break
}
return nil, err
}
str := strings.TrimSpace(string(b))
//配置檔案中的註釋
if strings.Index(str, "#") == 0{
continue
}
//配置檔案中的字首處理
n1 := strings.Index(str, "[")
n2 := strings.LastIndex(str, "]")
if n1 > -1 && n2 > -1 && n2 > n1 + 1{
config.strcet = strings.TrimSpace(str[n1 + 1 : n2])
continue
}
if len(config.strcet) < 1{
continue
}
//
eqIndex := strings.Index(str, "=")
if eqIndex < 0{
continue
}
eqLeft := strings.TrimSpace(str[0:eqIndex])
if len(eqLeft) < 1{
continue
}
eqRight := strings.TrimSpace(str[eqIndex+1:])
pos := strings.Index(eqRight,"\t#")
val := eqRight
if pos > -1{
val = strings.TrimSpace(eqRight[0:pos])
}
pos = strings.Index(eqRight, " #")
if pos > -1{
val = strings.TrimSpace(eqRight[0:pos])
}
pos = strings.Index(eqRight, "\t//")
if pos > -1{
val = strings.TrimSpace(eqRight[0:pos])
}
pos = strings.Index(eqRight, " //")
if pos > -1{
val = strings.TrimSpace(eqRight[0:pos])
}
if len(val) < 1{
continue
}
key := config.strcet + middle + eqLeft
config.ConfigMap[key] = strings.TrimSpace(val)
}
return config, nil
}
然後再有一個按key來獲取配置的val的字串的函式:
func (self *IniConfig) Get(key string)string{
v, ok := self.ConfigMap[key]
if ok{
return v
}
return ""
}
剩下來就是對於Config介面的實現了:
func (self *IniConfig) GetString(key string)string{
return self.Get(key)
}
func (self *IniConfig) GetInt(key string)(int, error){
return strconv.Atoi(self.Get(key))
}
func (self *IniConfig) GetInt64(key string)(int64, error){
return strconv.ParseInt(self.Get(key), 10, 64)
}
func (self *IniConfig) GetFloat(key string)(float64, error){
return strconv.ParseFloat(self.Get(key), 64)
}
func (self *IniConfig) GetBool(key string)(bool, error){
return strconv.ParseBool(self.Get(key))
}
ini_config.go的實現就這些。當然了,package和import也是肯定有的啦:
package conf
import (
"strings"
"strconv"
"io"
"bufio"
"os"
)
上面的這些程式碼整合到一起就是ini_config.go的完整程式碼了。
測試
上面那些,也就簡單的實現了配置檔案的讀取功能了。但是能不能用呢?我們簡單的做個測試吧。
/example/config/app.config
中寫一些簡單的配置資訊:
[default]
string = string
int = 10
int64 = 100000
float = 123.456
bool = true
然後在/example/test_config.go
讀取試一下:
package main
import(
"fmt"
"igo/conf"
)
func main(){
config,err := conf.NewConfig("ini", "config/app.config")
if err != nil{
fmt.Println(err.Error())
return
}
strVal := config.GetString("default.string")
fmt.Println("string value:", strVal)
intVal, err := config.GetInt("default.int")
if err != nil{
fmt.Println("get int value error: ", err.Error())
}
fmt.Println("int value: ", intVal)
int64Val, err := config.GetInt64("default.int64")
if err != nil{
fmt.Println("get int64 value error: ", err.Error())
}
fmt.Println("int64 value: ", int64Val)
floatVal, err := config.GetFloat("default.float")
if err != nil{
fmt.Println("get float value error: ", err.Error())
}
fmt.Println("float value: ", floatVal)
boolVal, err := config.GetBool("default.bool")
if err != nil{
fmt.Println("get bool value error: ", err.Error())
}
fmt.Println("bool value: ", boolVal)
}
結果如下:
完
轉載請註明出處: iGO實現之路 —— Config
相關文章
- Spring Cloud Config 實現配置中心SpringCloud
- 使用HazelCast實現Spring Config Server配置ASTSpringServer
- CA 雲架構的實現之路架構
- Consul Config 使用Git做版本控制的實現Git
- MySQL實現無密碼登入(mysql_config_editor)MySql密碼
- vue元件之路之輪播圖的實現Vue元件
- 高效能IOT伺服器實現之路伺服器
- Android 專案重構之路:實現篇Android
- 核心config檔案開啟CONFIG_DEVMEM後出現For kernel requirements at matrix level 5, For config CONFIG_DEVMEM, value = y but required ndevUIREM
- koa+mysql實現增刪改查-全棧之路MySql全棧
- Spring Cloud Config 實現配置中心,看這一篇就夠了SpringCloud
- express+mongodb+vue實現增刪改查-全棧之路ExpressMongoDBVue全棧
- express+mongodb+vue實現增刪改查-全棧之路2.0ExpressMongoDBVue全棧
- 跟我一起學.NetCore之路由的最佳實現NetCore路由
- 學習之路 / goroutine 併發協程池設計及實現Go
- 波場首個GameFi專案WIN NFT HORSE將與幣安聯合推出IGOGAMGo
- 前端之路: 用github的webhooks實現專案自動化構建前端GithubWebHook
- git configGit
- 申通的雲原生實踐之路:如何實現應用基於容器的微服務改造?微服務
- Laravel 搭建 Composer 包,實現配置 Config、門面 Facade、服務 Service、釋出到 packagistLaravel
- 歷史系統的現代化改造之路
- 中原銀行 Arthas 實踐之路
- Flutter實戰之路由功能篇Flutter路由
- 聚美元件化實踐之路元件化
- PHP實踐之路(目錄索引)PHP索引
- 自動駕駛資料閉環:實現高階自動駕駛的必由之路自動駕駛
- 描述 Machine.Config 和 Web.Config(轉載)MacWeb
- web.configWeb
- pkg-config
- config.py
- 聊聊「低程式碼」的實踐之路
- PHP實踐之路(六)控制結構PHP
- PHP實踐之路(七)PHP函式PHP函式
- Swift 演算法實戰之路(一)Swift演算法
- Swift 演算法實戰之路(二)Swift演算法
- 江波獲客隊助力合人機械實現數字化營銷之路
- Python學習之路25-使用一等函式實現設計模式Python函式設計模式
- 前端表單進階之路:通過 Vue.js 實現表單可配置化前端Vue.js