bytes 包提供了字节切片进行读写操作的一系列函数,字节切片处理的函数比较多分为基本处理函数、比较处理函数、后缀检查函数、索引函数、分割函数、大小写处理函数和子切片处理函数等
常用函数
类型转换
func testTrans() {
var i int = 100
var b byte = 10
b = byte(i) // 把i强制转换为byte
i = int(b)
var s string = "hello world"
b1 := []byte{1, 2, 3}
s = string(b1) // 把字节切片转成字符串
b1 = []byte(s) // 把字符串转成字节切片
}
Contains
func testContains() {
s := "duoke360.com"
b := []byte(s)
b1 := []byte("duoke360")
b2 := []byte("Duoke360")
strings.Contains("hello world", "hello") // 判断hello world是否含有hello
b3 := bytes.Contains(b, b1)
fmt.Printf("b3: %v\n", b3) // true
b3 = bytes.Contains(b, b2)
fmt.Printf("b3: %v\n", b3) // false
}
Count
func testCount() {
s := []byte("helloooooooooo")
sep1 := []byte("h")
sep2 := []byte("l")
sep3 := []byte("o")
fmt.Printf("bytes.Count(s, sep1): %v\n", bytes.Count(s, sep1)) // 1
fmt.Printf("bytes.Count(s, sep2): %v\n", bytes.Count(s, sep2)) // 2
fmt.Printf("bytes.Count(s, sep3): %v\n", bytes.Count(s, sep3)) // 10
}
Repeat
func testRepeat() {
b := []byte("hello")
fmt.Printf("bytes.Repeat(b, 1): %v\n", string(bytes.Repeat(b, 1))) // hello
fmt.Printf("bytes.Repeat(b, 3): %v\n", string(bytes.Repeat(b, 3))) // hellohellohello
}
Replace
func testReplace() {
s := []byte("hello world")
old := []byte("o")
news := []byte("ee")
fmt.Println(string(bytes.Replace(s, old, news, 0))) // hello world 0次 不替换
fmt.Println(string(bytes.Replace(s, old, news, 1))) // hellee world 1次 替换一个o
fmt.Println(string(bytes.Replace(s, old, news, 2))) // hellee weerld 2次 替换2个o
fmt.Println(string(bytes.Replace(s, old, news, -1))) // hellee weerld -1次 替换若干个个o
}
Runes
func testRunes() {
s := []byte("你好世界")
r := bytes.Runes(s)
fmt.Println("转换前字符串的长度: ", len(s)) // 12 一个汉字3个字节
fmt.Println("转换后字符串的长度: ", len(r)) // 4 一个汉字3个字节
}
Join
func testJoin() {
s2 := [][]byte{[]byte("你好"), []byte("世界")}
sep1 := []byte(",")
fmt.Println(string(bytes.Join(s2, sep1))) // 你好,世界
sep2 := []byte("#")
fmt.Println(string(bytes.Join(s2, sep2))) // 你好#世界
}
Reader类型
Reader 实现了 io.Reader, io.ReaderAt, io.WriterTo, io.Seeker, io.ByteScanner, io.RuneScanner 接口, Reader 是只读的,可以 seek
func testReader() {
data := "123456789"
// 通过[]byte创建Reader
re := bytes.NewReader([]byte(data))
// 返回未读取部分的长度
fmt.Println("re len: ", re.Len()) // 9
// 返回底层数据总长度
fmt.Println("re size: ", re.Size()) // 9
buf := make([]byte, 2) // 每次读取2字节
for {
// 读取数据
n, err := re.Read(buf)
if err != nil {
break
}
fmt.Printf("string(buf[:n]): %v\n", string(buf[:n])) // 12 34 56 78 9
}
// 设置偏移量 因为上面操作已经修改了读取位置等信息
re.Seek(0, 0)
for {
// 一个字节一个字节读取
b, err := re.ReadByte()
if err != nil {
break
}
fmt.Printf("string(b): %v\n", string(b)) // 1 2 3 4 5 6 7 8 9
}
re.Seek(0, 0)
off := int64(0)
for {
// 指定偏移量读取
n, err := re.ReadAt(buf, off)
fmt.Printf("n: %v\n", n) // 1
if err != nil {
break
}
off += int64(n)
fmt.Println(off, string(buf[:n])) // 2 12 4 34 6 56 8 78 1
}
}
Buffer类型
缓冲区具有读取和写入方法的可变大小的字节缓冲区。 Buffer 的 0 值是准备使用的空缓冲区
声明 Buffer 的四种方法:
var b bytes.Buffer // 直接定义一个Buffer变量 不用初始化 直接使用
b := new(bytes.Buffer) // 使用New返回Buffer变量
b:=bytes.NewBuffer(s []byte) // 从一个[]byte切片 构造一个Buffer
b:=bytes.NewBufferString(s string) // 从一个string变量 构造一个Buffer
func testBuffer() {
var b bytes.Buffer
fmt.Printf("b: %v\n", b) // b: {[] 0 0}
var b1 = bytes.NewBufferString("hello")
fmt.Printf("b1: %v\n", b1) // b1: hello
var b2 = bytes.NewBuffer([]byte("hello"))
fmt.Printf("b2: %v\n", b2) // b2: hello
}
WriteString
func testBuffer2() {
var b bytes.Buffer
n, _ := b.WriteString("hello") // 把hello写入bytes.Buffer b中
fmt.Printf("n: %v\n", n) // n: 5
fmt.Printf("b.Bytes(): %v\n", string(b.Bytes())) // b.Bytes(): hello
}
Read
func testBuffer3() {
var b = bytes.NewBufferString("hello world")
b1 := make([]byte, 2)
for {
n, err := b.Read(b1)
if err == io.EOF {
break
}
fmt.Printf("n: %v\n", n) // n: 2
fmt.Printf("string(b1): %v\n", string(b1)) // string(b1): he ...
}
}