filepath的使用

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
func main() {
// 返回所给路径的绝对路径
path, _ := filepath.Abs("./filepath.go")
fmt.Println(path)

// 返回路径的最后一个元素
fmt.Println(filepath.Base("./filepath.go"))
// 如果路径为空字符串,返回.
fmt.Println(filepath.Base(""))
// 如果路径只有斜线,返回/
fmt.Println(filepath.Base("///"))

// 返回元素的目录路径
// 路径为空则返回.
fmt.Println(filepath.Dir("/a/b/c.txt")) // /a/b

//返回等价的最短路径
//1.用一个斜线替换多个斜线
//2.清除当前路径.
//3.清除内部的..和他前面的元素
//4.以/..开头的,变成/
fmt.Println(filepath.Clean("C:/a/b/../c")) // C:/a/c
fmt.Println(filepath.Clean("./1.txt")) // 1.txt

// 获取指定路径文件的扩展名
// 如果没有点则返回空
fmt.Println(filepath.Ext("/a/b/c.go")) // .go

// 判断指定路径是否是一个绝对路径
fmt.Println(filepath.IsAbs("/a/b/c")) // true
fmt.Println(filepath.IsAbs("./a/b/c")) // false

// 拼接路径
dir, _ := filepath.Abs("/opt/cmdb")
fmt.Println(filepath.Join(dir, "config", "conf.ini")) // /opt/cmdb/config/conf.ini

// 返回指定路径的目录和文件名
Dir, base := filepath.Split("/etc/nginx/nginx.conf")
fmt.Println(Dir, base) // /etc/nginx/ nginx.conf

//将路径使用路径列表分隔符分开,见os.PathListSeparator
//linux下默认为:,windows下为;
paths := "/etc/nginx.conf:/etc/my.cnf:/etc/zookeeper.conf"
fmt.Println(filepath.SplitList(paths)) // [/etc/nginx.conf /etc/my.cnf /etc/zookeeper.conf]

// 返回指定路径下的特定文件,类似于linux的find
fmt.Println(filepath.Glob("./*.go"))

//匹配文件名,完全匹配则返回true
fmt.Println(filepath.Match("*", "a"))
fmt.Println(filepath.Match("*", "C:/a/b/c"))
fmt.Println(filepath.Match("\\b", "b"))
}

strings.Builder|Reader使用

不论是Builder还是Reader都是在内存中操作字符串的

Builder示例

与许多支持string类型的语言一样,golang中的string类型也是只读且不可变的。因此,这种拼接字符串的方式会导致大量的string创建、销毁和内存分配问题。可以使用strings.Builder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func main() {
// 声明变量s为Builder类型
var s strings.Builder

// 写入字符串类型
s.WriteString("我爱Go语言\n")
// 写入字节类型
s.Write([]byte("运维开发"))
// 写入rune类型,码点
s.WriteRune('b')
// 直接写入字节
s.WriteByte('c')

// 打印出内容
fmt.Println(s.String())

// 获取Builder的字节长度
fmt.Println(s.Len())
// 清空Builder内容
s.Reset()
fmt.Println(s.Len())
}

Reader示例

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
func main() {
reader := strings.NewReader("abcdefghijklmn123456789")

// 从reader中读出3个字节
//ctx := make([]byte, 3)
//n,err := reader.Read(ctx)
//fmt.Println(n,err,string(ctx[:n]))

// 定义一个切片,用于存放读取的内容
ctx := make([]byte, 10)
for {
// 读取内容到切片中, n为读取的字节数量,err用于判断是否发生错误或者是否读取到文件末尾了。
n, err := reader.Read(ctx)
if err != nil { // 发生错误就跳出循环
break
}
fmt.Println(n, err, string((ctx[:n])))
}


// 通过seek设置偏移量,重新从内存中读取内容
reader.Seek(0, io.SeekStart)
n, err := reader.Read(ctx)
// 重新读取10个字节内容
fmt.Println(n, err, string((ctx[:n])))


// 或者reader的字符串长度
fmt.Println(reader.Size())


// 重新设置reader的字符串内容,重新读会显示新的内容了
reader.Reset("123123123")
n, err = reader.Read(ctx)
// 重新读取10个字节内容
fmt.Println(n, err, string((ctx[:n]))) // 9 <nil> 123123123

// 将reader对象中内容输出到输出流
reader.WriteTo(os.Stdout)
}

bytes Buffer使用

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
func main() {
// 通过字节切片创建buffer结构体指针对象
buffer1 := bytes.NewBuffer([]byte("abc,"))

// 通过字符串创建buffer结构体指针
buffer2 := bytes.NewBufferString("123,")

// 写操作
buffer1.Write([]byte("xyz,"))
buffer2.Write([]byte("789,"))

buffer1.WriteString("mn")
buffer2.WriteString("55")

// 读内容
ctx := make([]byte,3)
n,_ := buffer1.Read(ctx)
fmt.Println(string(ctx[:n])) // abc

n,_ = buffer2.Read(ctx)
fmt.Println(string(ctx[:n])) // 123

// 当碰到指定的字节元素后停止读取
ctx,_ = buffer2.ReadBytes(',')
fmt.Println(string(ctx))

ctx,_ = buffer1.ReadBytes(',')
fmt.Println(string(ctx))

txt,_ := buffer1.ReadString(',')
fmt.Println(string(txt)) // xyz,

txt,_ = buffer2.ReadString(',')
fmt.Println(string(txt)) // 789,

// 将buffer流中剩余内容转换成字节切片
fmt.Println(string(buffer1.Bytes())) // nn

// 将buffer流中剩余内容转换成字节切片
fmt.Println(buffer1.String()) // mn

buffer1.WriteTo(os.Stdout)

buffer2.Reset() // 清空内容
buffer2.WriteTo(os.Stdout)
}