go标准库之bytes模块

377 阅读3分钟

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类型

缓冲区具有读取和写入方法的可变大小的字节缓冲区。 Buffer0 值是准备使用的空缓冲区

声明 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 ...
	}
}