go语言解析INI文件
package main import ( "bufio" "bytes" "io" "os" "unicode" ) const ( stat_none = iota stat_group stat_key stat_value stat_comment ) type Attr struct { Name string Value string Comment string next *Attr } type Element struct { Element string Attr *Attr next *Element } type Decoder struct { state int b byte t bytes.Buffer r io.ByteReader err error m *Element n string } func (d *Decoder) getAttr(m *Element, e string) string { for n := m.Attr; nil != n; n = n.next { if e == n.Name { return n.Value } } return "" } func (d *Decoder) GetElement(e string, a string) string { for n := d.m; nil != n; n = n.next { if e == n.Element { return d.getAttr(n, a) } } return "" } func (d *Decoder) newAttrNextComment(value string) { d.m.Attr.Comment = value println(value) } func (d *Decoder) newAttrNext(name string, value string) { attr := new (Attr) attr.Name = name attr.Value = value if nil == d.m.Attr { attr.next = nil } else { attr.next = d.m.Attr } d.m.Attr = attr } func (d *Decoder) newElement(name string) { element := new (Element) element.Element = name element.Attr = nil if nil == d.m { element.next = nil } else { element.next = d.m } d.m = element } func (d *Decoder) switchToMap() { for { d.b, d.err = d.r.ReadByte() if d.err != nil { break } switch d.state { case stat_none: if d.b == '[' { d.state = stat_group } else if d.b == ';' { d.state = stat_comment } else if !unicode.IsSpace(rune(d.b)) { d.state = stat_key d.t.WriteByte(byte(d.b)) } break case stat_group: if d.b == ']' { d.state = stat_none d.newElement(d.t.String()) d.t.Reset() } else if !unicode.IsSpace(rune(d.b)) { d.t.WriteByte(byte(d.b)) } break case stat_key: if d.b == '=' { d.state = stat_value d.n = d.t.String() d.t.Reset() } else if !unicode.IsSpace(rune(d.b)) { d.t.WriteByte(byte(d.b)) } break case stat_value: if !unicode.IsSpace(rune(d.b)) { d.t.WriteByte(byte(d.b)) } else { d.state = stat_none d.newAttrNext(d.n, d.t.String()) d.t.Reset() } break case stat_comment: if !unicode.IsSpace(rune(d.b)) { d.t.WriteByte(byte(d.b)) } else { d.state = stat_none d.newAttrNextComment(d.t.String()) d.t.Reset() } break default : d.state = stat_none break } } } func (d *Decoder) switchToReader(r io.Reader) { if rb, ok := r.(io.ByteReader); ok { d.r = rb } else { d.r = bufio.NewReader(r) } d.switchToMap() } func NewDecoder(r io.Reader) *Decoder { d := &Decoder{} d.switchToReader(r) return d } func main() { xmlFile, err := os.Open( "hh.ini" ) if nil != err { return } defer xmlFile.Close() d := NewDecoder(xmlFile) println(d.GetElement( "aaaa" , "ac" )) } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· dotnet 9 通过 AppHostRelativeDotNet 指定自定义的运行时路径
· 如何统计不同电话号码的个数?—位图法
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 从零实现富文本编辑器#3-基于Delta的线性数据结构模型
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 用c#从头写一个AI agent,实现企业内部自然语言数据统计分析
· 三维装箱问题(3D Bin Packing Problem, 3D-BPP)
· Windows上,10分钟构建一个本地知识库
· 使用 AOT 编译保护 .NET 核心逻辑,同时支持第三方扩展
· Java虚拟机代码是如何一步一步变复杂且难以理解的?