properties

package module
v0.0.0-...-f7140f5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 17, 2020 License: BSD-3-Clause Imports: 10 Imported by: 3

README

Overview

Build Status GoDoc Language License codecov goreport

*.properties文件是java里面很常见的配置文件。这里是一个go语言版的*.properties文件处理库。 本库支持properties文件的读取、修改、回写操作。 也支持向properties文件中的属性追加、删除注释操作。

properties文件格式定义

为了使得properties文件的识别更加简单快速,go的properties的文件格式和java的properties文件并不是等价的。它将java里面一些很少用到的格式特性都去掉了。

golang版本的properties文件的格式定义如下:

  • 一行如果第一个非空白字符是#或者!,那么整行将被识别为注释行,注释行将被解析器忽略。

    比如,下面三行都会被解析器忽略(第三行是空白行):

    #  这是注释行
    !  这也是注释行
    
    
  • 每个配置项都是单行的key-value对,不支持跨行,key和value以=或者:分隔。

    比如,下面其实是三个配置项----UserName=Fabirc \Boch=Contry=US

    UserName = Fabirc \
    Boch
    Contry=US
    
  • key和value都是区分大小写;

    比如,下面其实是三个不同的配置项:

    SizeRange=1-20
    sizerange=1-20
    SIZERANGE=1-20
    
  • 一行的第一个=即使key与value的分隔字符,所以key中不会出现=,但value部分可以出现=

    比如,下面这个第一个行的key为expr,value是A-B=C;而第二行的key是一个""(空字符串),value是Hello。当然第二种情况并没有实际意义:

    expr=A-B=C
    =Hello
    
  • key和value的前后的空白都将被忽略,但key和value中间的空白会被原样保留;

    比如,下面这三个配置项的值都是1-20

      SizeRange-1=1-20
    SizeRange-2 =  1-20   
       SizeRange-3  =  1-20  
    
  • properties文件只支持**UTF-8**字符集,所以value中可以直接输入中文,遇到中文字符不必像java那样使用\uxxxx转义,直接用中文字面文字即可;

    比如,下面这个配置项的key为地址,value为深圳

      地址=深圳
    
  • 当value为空时,等号可忽略;

    所以,下面三个配置项的值都是空字符串(第一个等号后面有个):

    Address-1=  
    Address-2=
    Address-3
    

接口定义

属性文档

一个properties文档由一个properties.Doc对象来表示。一个properties文档由多个key-value形式的属性组成。每个属性还可以追加一行或者多行注释。

加载属性文档

properties.Load 从io流生成一个properties.Doc对象。

doc, err := properties.LoadFile("test1.properties")
if nil != err {
    t.Error("加载失败")
    return
}

fmt.Println(doc.String("key"))
创建一个新的属性文档对象

properties.New 直接创建一个新的属性文档对象,常用于属性创建文档文件的场景下。我们随后可以通过properties.Export函数将属性文档导出到字符串。

doc := properties.New()
doc.Set("a", "aaa")
doc.Comment("a", "This is a comment for a")

doc.Export()
将属性回写到文件或者流

properties.Save 可用于将一个文档回写到指定的writer中去。

buf := bytes.NewBufferString("")
doc.Save(buf)
属性值的读取
  • 通用读取能力

Doc对象的Get方法提供了一个基本的元素读取能力:

func (p Doc) Get(key string) (value string, exist bool)

Get函数会返回两个参数,当对应的key在Doc文档中存在时,会返回该key对应的value,且exist的值将为true;如果不存在,exist的值将是false。

我们经常利用Get来探测,某个指定key的属性是否在属性文件中定义了。

  • 读取并转换 读取属性然后转成对应的数据类型是个很常见的任务,所以Doc为最常用的几种类型提供了方便的读取并转换的函数。

    • Str() 读取一个字符串型的属性,如果不存在默认返回""
    • Int() 读取一个属性并转换为int类型,如果key对应的属性不存在,或者转换失败,返回值为0
    • Int64() 读取一个属性并转换为int64类型,如果key对应的属性不存在,或者转换失败,返回值为0
    • Uint64()Int()函数类似,只是返回的数据类型为uint64
    • Float64() 也是和Int()函数类似,但返回值为float64
    • Bool() 同与String类似,只是返回值是bool类型的且缺省值是falseBool函数会将1, t, T, true, TRUE, True识别为true,将0, f, F, false, FALSE, False识别为false
    • Object() 这个函数提供了一个数据映射能力,可以将找到的value映射为任何类型。
  • 指定读取的缺省值 前面的Str()Int()等函数在key不存在或者抓换失败的场景下,默认会返回零值。但零值往往不能满足我们的诉求,我们经常需要自己指定这些场景下的返回值。 StrOrIntOrFloatOrBoolOrObjectOr 这几个函数的返回值和前面不带Or后缀的函数的行为类似,只是当配置项不存在时或者数据格式错误时,会直接返回参数中的def(缺省值)。

属性的增删改
  • 增加或者修改属性

Set()函数用于修改指定的key的属性的值。如果指定的key的属性不存在,那么自动创建一个。

本库并没有提供按类型设置属性值的功能,前面描述的Set()函数只接受字符串类型的属性值作为输入。主要原因是数据的转换方式非常多,没有一种普适 的数据转换方法。所以,对于非字符串类型的值的设置需要自行转换成string类型。

doc.Set("key", "value")
  • 处理属性不存在的场景

当属性不存在时,Set()函数会新建一个属性值,这种工作方式通常是很有用的。但是,有时候我们不希望Set()的这种自作聪明的行为。此时,我们可以通过Get()方法判断一些以确定是否需调用Set()

_, exist := doc.Get("key")
if !exist {
    return errors.New("Key is not exist")
}

doc.Set("key", "New-Value")
  • 删除属性

Del()函数用于删除指定key的属性。它会返回一个bool值,用于表示当前的key的属性是否存在。

exist := doc.Del("key")
操作注释

在本库中,注释是绑定到属性的。位于属性的key-value定义前面,且与属性之间没有空白行的多行注释,我们会判定这些注释是属于该属性的,比如:

 # Comment1
 # Comment2
 
 # Comment3
 # Comment4
 mykey=myvalue

上面的Comment3和Comment4是mykey属性的注释,但是Comment1和Comment2却不是。

Doc的Comment()函数用于为属性指定一些注释,允许指定多行注释。而Uncomment()函数用于删除指定的key的所有注释。

文档对象枚举

Doc的Accept()Foreach()函数都是用来对文档对象进行枚举的,但是Foreach()专用于对属性进行遍历。而Accept()可以通过对属性和注释进行遍历。

实际上,Save()函数就是利用Accept()函数来实现的:

func (p Doc) Save( writer io.Writer) {
    p.Accept(func(typo byte, value, key string) bool {
        switch typo {
        case '#', '!', ' ':
            fmt.Fprintln(writer, value)
        case '=', ':':
            fmt.Fprintf(writer, "%s%c%s\n", key, typo, value)
        }
        return true
    })
}

Accept()函数的回调函数里面有个typo参数,这个参数决定了当前这条记录是注释还是一个有效的属性。typo的取值可能有下面一些:

  • '#' 表示当前的value是#开头的注释
  • '!' 表示当前的value是!开头的注释
  • ' ' 表示当前的value是个空行或者空白行
  • '=' 表示当前的value是个以=分隔的属性
  • ':' 表示当前的value是个以:分隔的属性

更多参考

  1. 原始代码 https://github.com/tinyhubs/properties
  2. 其它实现 https://github.com/magiconair/properties

Documentation

Overview

Package properties is used to read or write or modify the properties document.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Diff

func Diff(l, r *Doc, f func(DiffEvent))

Diff diffs l to r.

Types

type ChangeType

type ChangeType int

ChangeType defines the type of chaging.

const (
	// Modified ...
	Modified ChangeType = iota
	// Added ...
	Added
	// Removed ...
	Removed
	// Same ...
	Same
)

type DiffEvent

type DiffEvent struct {
	ChangeType ChangeType
	Key        string
	LeftValue  string
	RightValue string
}

DiffEvent defines ChangeEvent for properties diff

type Doc

type Doc struct {
	// contains filtered or unexported fields
}

Doc The properties document in memory.

func Load

func Load(reader io.Reader) (doc *Doc, err error)

Load creates the properties document from a file or a stream.

func LoadBytes

func LoadBytes(s []byte) (doc *Doc, err error)

LoadBytes creates the properties document from a string.

func LoadFile

func LoadFile(file string) (doc *Doc, err error)

LoadFile creates the properties document from a file or a stream.

func LoadMap

func LoadMap(m map[string]string) (doc *Doc, err error)

LoadMap creates a new Properties struct from a string map. copy from https://github.com/magiconair/properties

func LoadString

func LoadString(s string) (doc *Doc, err error)

LoadString creates the properties document from a string.

func New

func New() *Doc

New creates a new and empty properties document.

It's used to generate a new document.

func (Doc) Accept

func (p Doc) Accept(f func(typo byte, value, key string) bool)

Accept traverses every line of the document, include comment.

The typo parameter special the line type. If typo is '#' or '!' means current line is a comment. If typo is ' ' means current line is a empty or a space line. If typo is '=' or ':' means current line is a key-value pair. The traverse will be terminated if f return false.

func (Doc) Bool

func (p Doc) Bool(key string) bool

Bool same as BoolOr but the def is false.

func (Doc) BoolOr

func (p Doc) BoolOr(key string, def bool) bool

BoolOr retrieve the bool value by key. If the line is not exist, the def will be returned. This function mapping "1", "t", "T", "true", "TRUE", "True" as true. This function mapping "0", "f", "F", "false", "FALSE", "False" as false. If the line is not exist of can not map to value of bool,the def will be returned.

func (*Doc) Comment

func (p *Doc) Comment(key, comments string) bool

Comment appends comments for the special line.

Return false if the special line is not exist.

func (*Doc) Del

func (p *Doc) Del(key string) bool

Del deletes the exist line.

If the line is not exist, return false.

func (Doc) Export

func (p Doc) Export() (string, error)

Export saves the doc to file or stream.

func (Doc) ExportFile

func (p Doc) ExportFile(file string) error

ExportFile saves the doc to file.

func (Doc) Float64

func (p Doc) Float64(key string) float64

Float64 same as Float64Or but the def is 0.0 .

func (Doc) Float64Or

func (p Doc) Float64Or(key string, def float64) float64

Float64Or retrieve the float64 value by key. If the line is not exist, the def will be returned.

func (Doc) Foreach

func (p Doc) Foreach(f func(value, key string) bool)

Foreach traverses all of the key-value pairs in the document. The traverse will be terminated if f return false.

func (Doc) Get

func (p Doc) Get(key string) (value string, exist bool)

Get retrieves the value from Doc.

If the line is not exist, the exist is false.

func (Doc) Int

func (p Doc) Int(key string) int

Int is same as IntOr but the def is 0 .

func (Doc) Int64

func (p Doc) Int64(key string) int64

Int64 is same as Int64Or but the def is 0 .

func (Doc) Int64Or

func (p Doc) Int64Or(key string, def int64) int64

Int64Or retrieves the int64 value by key. If the line is not exist, the def will be returned.

func (Doc) IntOr

func (p Doc) IntOr(key string, def int) int

IntOr retrieves the int value by key. If the line is not exist, the def will be returned.

func (Doc) Map

func (p Doc) Map() map[string]string

Map gets the map of properties

func (Doc) MustGet

func (p Doc) MustGet(key string) (value string)

MustGet returns the expanded value for the given key if exists or panics otherwise.

func (Doc) Object

func (p Doc) Object(key string, f func(k, v string) (interface{}, error)) interface{}

Object is same as ObjectOr but the def is nil.

Notice: If the return value can not be assign to nil, this function will panic/

func (Doc) ObjectOr

func (p Doc) ObjectOr(key string, def interface{}, f func(k, v string) (interface{}, error)) interface{}

ObjectOr maps the value of the key to any object. The f is the customized mapping function. Return def if the line is not exist of f have a error returned.

func (Doc) Populate

func (p Doc) Populate(b interface{}, tag string) error

Populate populates the properties to the structure's field.

func (Doc) Save

func (p Doc) Save(writer io.Writer) error

Save saves the doc to file or stream.

func (*Doc) Set

func (p *Doc) Set(key, value string)

Set updates the value of the line of the key.

Create a new line if the line of the key is not exist.

func (Doc) Str

func (p Doc) Str(key string) string

Str same as StrOr but the def is "".

func (Doc) StrOr

func (p Doc) StrOr(key, def string) string

StrOr retrieves the string value by key. If the line is not exist, the def will be returned.

func (Doc) String

func (p Doc) String() string

String gives the whole properties as a string

func (Doc) Uint64

func (p Doc) Uint64(key string) uint64

Uint64 same as Uint64Or but the def is 0 .

func (Doc) Uint64Or

func (p Doc) Uint64Or(key string, def uint64) uint64

Uint64Or Same as Int64Or, but the return type is uint64.

func (*Doc) Uncomment

func (p *Doc) Uncomment(key string) bool

Uncomment removes all of the comments for the special line.

Return false if the special line is not exist.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL