Go:读配置文件程序包的程序

核心任务:包必须提供一个函数 Watch(filename,listener) (configuration, error)

  • 输入 filename 是配置文件名
  • 输入 listener 一个特殊的接口,用来监听配置文件是否被修改,让开发者自己决定如何处理配置变化
    • type ListenFunc func(string)
    • type inteface Listener { listen(inifile string) }
    • ListenFunc 实现接口方法 listen 直接调用函数
    • 优点
      • 所有满足签名的函数、方法都可以作为参数
      • 所有实现 Listener 接口的数据类型都可作为参数
  • 输出 configuration 数据类型,可根据 key 读对应的 value。 key 和 value 都是字符串
  • 输出 error 是错误数据,如配置文件不存在,无法打开等
  • 可选的函数 WatchWithOption(filename,listener,...) (configuration, error

简单使用:

测试demo,包含在readme里的简单例子

 

 测试过程gif,当处于监听过程中的时候,如果修改test.ini文件,可以监听到文件发生修改。

 

 

TestReadFile(自动测试,读取文件是否符合和储存文件是否一致)

ReadFile文件是

使用了Map

 

 测试函数(借鉴了别的同学的测试函数,感谢!)

 

 

自定义错误类型

 

 

 

实现监听函数

 

 

 

判断系统类型

 

 

关于API部分生成:

例子:我想要生成某个文件夹下的go文档,假设你的gopath是D:/code  你项目目录是D:\code\src\下的test,你想生成test 项目中的testcode文件夹下的所有go的doc;那么需要执行如下步骤。
第1步、那么在命令行中进入到该文件夹下 D:\code\src\test,执行 godoc -http=:6060
第2步、打开浏览器输入http://127.0.0.1:6060/pkg/test 
妥了

 

在ubuntu环境下还要下载一个go工具包,按照提示安装就可以了

部分截图:

 

 

watch.go完整代码:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package watchFile
 
import (
    "bufio"
    "fmt"
    "os"
    "runtime"
    "strings"
    "io"
)
 
//创建一个自定义的错误类型
func New(text string) errorString {
    return errorString{text}
}
 
//错误信息的数据结构
type errorString struct {
    s string
}
 
//错误的方法:打印错误信息并返回错误信息
func (e *errorString) Error() string {
    fmt.Fprintf(os.Stdout, e.s)
    return e.s
}
 
 
//根据路径参数读取配置文件,并且返回一个储存配置文件键值对的map和自定义的错误类型
func readFile(iniFile string) (map[string]string, errorString) {
 
    temConfig := map[string]string{}
    var error errorString           
 
    _, err := os.Stat(iniFile)
    if err != nil {
        error = New("error1:The configuration file is not in the current path")
        return temConfig, error
    }
 
    Filein, err1 := os.OpenFile(iniFile, os.O_RDONLY, 0644)
    if err1 != nil {
        error = New("error1: Failed to open file")
        return temConfig, error
    } else {
        error = New("")
    }
     
    buffin := bufio.NewReader(Filein)
     
    for {
        line, err2 := buffin.ReadString('\n')
        if (err2 == io.EOF) {
            break
        }
        var i int
         
        for i = 0; i < len(line); i++ {
            if line[i] != ' ' && line[i] != '\t' {
                break
            }
        }
         
        if i == len(line) {
            continue
        }
         
        if line[i] == '#' || line[i] == ';' || line[i] == '[' {
            continue
        }
        keyStart := i 
        lastBlank := i
         
        for i = 0; i < len(line); i++ {
            if line[i] == '=' {
                break
            }
            if line[i] == ' ' {
                lastBlank = i
            }
        }
         
        if i >= len(line)-1 {
            continue
        }
        if lastBlank == keyStart {
            lastBlank = i
        }
         
        keyString := line[keyStart:lastBlank]
 
         
        valueString := line[i+2: len(line) - 1]
 
        valueString = strings.Replace(valueString, "\n", "", -1)
        valueString = strings.Replace(valueString, "\t", "", -1)
         
        temConfig[keyString] = valueString
         
        if err2 != nil {
            break
        }
    }
    _ = Filein.Close();
 
    return temConfig, error
}
 
//打印map
func printConfig(conf map[string]string) {
    fmt.Printf("File content : \n")
    for key, value := range conf {
        fmt.Printf("%s = %s\n", key, value)
    }
    fmt.Printf("\nEnd ------------ : \n")
}
 
//比较两个map是否相同
func mapCompare(map1 map[string]string, map2 map[string]string) bool {
 
     
    for key1, value1 := range map1 {
        value2, _ := map2[key1]
        if value1 != value2 {
            return false
        }
    }
     
    if len(map2) > len(map1) {
        return false
    }
    return true
}
 
 
type ListenFunc func(string)
 
//接口
type Listener interface {
    listen(inifile string)
}
 
//函数签名ListenFunc实现接口方法
func (Listen ListenFunc) listen(inifile string) {
    config1, _ := readFile(inifile)
    print("Listening :\n")
    for {
        temConfig, _ := readFile(inifile)
        if !mapCompare(config1, temConfig) {
            break
        }
    }
}
 
var symbol byte //注释符
//判断系统类型,根据系统类型判断注释符
func initSys() {
    sysType := runtime.GOOS
    if sysType == "linux" {
        symbol = '#'
    } else if sysType == "window" {
        symbol = ';'
    }
}
 
//读取文件,然后监听文件,如果文件在监听期间修改,则打印返回最新文件,并结束
func Watch(filename string, Listen Listener) (map[string]string, errorString) {
    initSys()
 
    config, error1 := readFile(filename)
    if len(error1.s) > 0 {
        fmt.Printf("An error occurs in function Watch : %s", error1.s)
        return config, error1
    }
    printConfig(config)
    Listen.listen(filename)
    print("The configuration file has changed :\n")
    config, error1 = readFile(filename)
    if len(error1.s) > 0 {
        fmt.Printf("An error occurs in function Watch : %s", error1.s)
    }
    printConfig(config)
    return config, error1
}

 

posted @   woodx  阅读(240)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示