配置文件读写

  • 使用ini为后缀的配置文件

  • 使用第三方库为

    go get gopkg.in/gcfg.v1
    
  • 代码样例

    package main
    
    import(
    	"os"
    	"fmt"
    	"log"
    	"time"
    	"gopkg.in/gcfg.v1"
    )
    var path string = "conf.ini"
    var config *Config
    
    // 获取配置文件相对应的信息
    type Config struct{
    	User map[string]*struct{
    		UID string
    		Pid string
    	}
    }
    
    
    func init(){
    	log.SetFlags(log.Lshortfile|log.Ltime)
    	config = &Config{}
    }
    
    // 读取
    func readConfig()(err error){
    	if path==""{
    		err =  fmt.Errorf("path is null")
    		log.Println(err)
    		return
    	}
    	log.Println("读取配置文件")
    	err = gcfg.ReadFileInto(config,path)
    	if err!=nil{
    		err = fmt.Errorf("Failed to parse config file:%s",err)
    		log.Println(err)
    		return
    	}
    	return
    }
    
    func prinfConfigInfo()(err error){
    	defer func(){
    		if r:=recover();r!=nil{
    			err = r.(error)
    		}
    	}()
    	log.Println("每个10秒打印配置文件")
    	ticker := time.NewTicker(10*time.Second)
    	for{
    		select {
    		case <-ticker.C:
    			for key,value := range config.User{
    				log.Printf("%v uid=%v pid=%v \n",key,key,value)
    			}
    		}
    	}
    }
    func main(){
    	fmt.Println("读取配置文件信息")
    	err := readConfig()
    	if err!=nil{
    		log.Println(err)
    		return
    	}
    	fmt.Println("打印配置信息")
    	err = prinfConfigInfo()
    	if err!=nil{
    		log.Println(err)
    	}
    }
    
  • 配置文件内容(conf.ini)

    [user "A"]
    uid = 45
    pid = 54
    
    [user "B"]
    uid = 12
    pid = 12
    

思考:在整个项目中,要是需要修改到配置文件,是否需要在手动停止项目,修改之后,在手动开启项目呢?

  • 手动的原因:内存中已经存有修改前的配置文件信息,要是单单修改配置文件,是不会把新的配置文件信息,存到内存中的。因此。。。。
  • 也可以不用,只要对配置文件进行热更新就行

样例代码

package main

import(
	"os"
	"fmt"
	"log"
	"time"
	"sync/atomic"
	"gopkg.in/gcfg.v1"
)
var path string = "conf.ini"
var lastModTime = time.Now().Unix() // 获取目前的时间
var config *Config

// 获取配置文件相对应的信息
type Config struct{
	User map[string]*struct{
		UID string
		Pid string
	}
}


func init(){
	log.SetFlags(log.Lshortfile|log.Ltime)
	config = &Config{}
}

// 读取
func readConfig()(err error){
	if path==""{
		err =  fmt.Errorf("path is null")
		log.Println(err)
		return
	}
	log.Println("读取配置文件")
	err = gcfg.ReadFileInto(config,path)
	if err!=nil{
		err = fmt.Errorf("Failed to parse config file:%s",err)
		log.Println(err)
		return
	}
	return
}

func prinfConfigInfo()(err error){
	defer func(){
		if r:=recover();r!=nil{
			err = r.(error)
		}
	}()
	log.Println("每个10秒打印配置文件")
	ticker := time.NewTicker(10*time.Second)
	for{
		select {
		case <-ticker.C:
			for key,value := range config.User{
				log.Printf("%v uid=%v pid=%v \n",key,key,value)
			}
		}
	}
}
func monitor(){
	log.Println("设置监听时间")
	ticker := time.NewTicker(10*time.Second)
	log.Println("启动监听器")
	for{
		select{
			case <-ticker.C:
				// 使用匿名函数是关闭文件
				func(){
					if path==""{
						err :=  fmt.Errorf("path is null")
						log.Println(err)
						return
					}
					fmt.Println("打开配置文件")
					file,err := os.Open("conf.ini")
					if err!=nil{
						err = fmt.Errorf("打开配置文件错误:%v",err)
						log.Println(err)
						return
					}
					defer file.Close()
					fmt.Println("获取配置信息")
					fileInfo,err := file.Stat()
					if err!=nil{
						err = fmt.Errorf("获取配置文件信息错误:%v",err)
						log.Println(err)
						return
					}
					modtime := fileInfo.ModTime()
					if modtime.Unix()>lastModTime{
						log.Println("配置文件已经修改啦,通知各个部门")
						lastModTime = modtime.Unix()
						err:= readConfig()
						if err!=nil{
							err = fmt.Errorf("重新读取配置文件错误:%v",err)
							log.Println(err)
							return
						}
					}else{
						return
					}
				}()					
		}
	}
}

func main(){
	fmt.Println("读取配置文件信息")
	log.Println("监听文件是否修改")
	go monitor()
	err := readConfig()
	if err!=nil{
		log.Println(err)
		return
	}
	fmt.Println("打印配置信息")
	err = prinfConfigInfo()
	if err!=nil{
		log.Println(err)
	}
}

总结

  • time.Ticker适合用来制作监听器
posted @ 2019-10-27 17:32  Myuniverse  阅读(278)  评论(0编辑  收藏  举报