[转载]golang语言中bytes包的常用函数,Reader和Buffer的使用

作者: Luan 分类: 转载 发布时间: 2017-12-05 13:28

本文转载自:https://www.cnblogs.com/jkko123/

golang语言中bytes包的常用函数,Reader和Buffer的使用

bytes中常用函数的使用:

package main;

import (
	"bytes"
	"fmt"
	"unicode"
)

//bytes包中实现了大量对[]byte操作的函数和两个最主要的Reader和Buffer两个结构

func main() {
	str := "aBcD";
	//转为小写
	fmt.Println(string(bytes.ToLower([]byte(str))));
	//转为大写
	fmt.Println(string(bytes.ToUpper([]byte(str))));
	//转为标题,
	fmt.Println(string(bytes.ToTitle([]byte(str))));

	//自定义映射表
	mycase := unicode.SpecialCase{
		unicode.CaseRange{
			//1,1表示替换规则只影响1到1之间的字符
			1,
			1,
			[unicode.MaxCase]rune{
				//大写转换
				'壹' - 1,
				//小写转换
				'一' - 1,
				//标题转换
				'小' - 1,
			},
		},
		unicode.CaseRange{
			2,
			2,
			[unicode.MaxCase]rune{
				'贰' - 2,
				'二' - 2,
				'中' - 2,
			},
		},
		unicode.CaseRange{
			3,
			3,
			[unicode.MaxCase]rune{
				'叁' - 3,
				'三' - 3,
				'大' - 3,
			},
		},
	};
	//使用映射表将[]byte中字符修改为小写
	data := bytes.ToLowerSpecial(
		mycase,
		[]byte{1, 2, 3},
	)
	fmt.Println(string(data));
	//使用映射表将[]byte中字符修改为大写
	data = bytes.ToUpperSpecial(
		mycase,
		[]byte{1, 2, 3},
	);
	fmt.Println(string(data));
	//使用映射表将[]byte中字符修改为标题
	data = bytes.ToTitleSpecial(
		mycase,
		[]byte{1, 2, 3},
	);
	fmt.Println(string(data));

	//将[]byte中单词首字符修改为Title并返回
	fmt.Println(string(bytes.Title([]byte("abc def"))));

	//比较两个[]byte,
	// a < b 返回 -1
	// a == b 返回 0
	// b > b 返回 1
	fmt.Println(bytes.Compare([]byte("a"), []byte("b")));

	//比较两个[]byte是否相等
	fmt.Println(bytes.Equal([]byte("abc"), []byte("abc")));

	//比较两个[]byte是否相等,忽略大写,小写,标题
	fmt.Println(bytes.EqualFold([]byte("ABC"), []byte("abc")));

	//去掉[]byte两边包含在cutset中的字符
	fmt.Println(string(bytes.Trim([]byte(" abc "), " ")));

	//去掉左边包含在cutset中的字符
	fmt.Println(string(bytes.TrimLeft([]byte(" abc "), " ")));

	//去掉右边包含在cutset中的字符
	fmt.Println(string(bytes.TrimRight([]byte(" abc "), " ")));

	//去掉两边空白字符
	fmt.Println(string(bytes.TrimSpace([]byte(" abc "))));

	//去掉前缀
	fmt.Println(string(bytes.TrimPrefix([]byte("tb_user"), []byte("tb_"))));

	//去掉后缀
	fmt.Println(string(bytes.TrimSuffix([]byte("user_idx"), []byte("_idx"))));

	//以sep为分隔符,切分为多个[]byte
	tmp := bytes.Split([]byte("ab cd ef"), []byte(" "));
	for _, v := range tmp {
		fmt.Println(string(v));
	}

	//分割最多n个子切片,超出n的部分将不进行切分
	tmp = bytes.SplitN([]byte("ab cd ef"), []byte(" "), 2);
	for _, v := range tmp {
		fmt.Println(string(v));
	}

	//以sep为分隔符,切分为多个[]byte,结果包含分隔符,在子串尾部
	tmp = bytes.SplitAfter([]byte("ab,cd,ef"), []byte(","));
	for _, v := range tmp {
		fmt.Println(string(v));
	}

	//分割最多n个子切片,超出n的部分将不进行切分
	tmp = bytes.SplitAfterN([]byte("ab,cd,ef"), []byte(","), 2);
	for _, v := range tmp {
		fmt.Println(string(v));
	}

	//以空白字符切分
	tmp = bytes.Fields([]byte("a b c d"));
	for _, v := range tmp {
		fmt.Println(string(v));
	}

	//以符合函数的字符作为分隔符来切分
	tmp = bytes.FieldsFunc([]byte("asbscsd"), func(r rune) bool {
		if r == rune('s') {
			return true;
		}
		return false;
	});
	for _, v := range tmp {
		fmt.Println(string(v));
	}

	//以sep为连接符,拼接[][]byte
	fmt.Println(string(bytes.Join(
		[][]byte{
			[]byte("aa"),
			[]byte("bb"),
			[]byte("cc"),
		},
		[]byte("-"),
	)));

	//重复[]byte,Count次
	fmt.Println(string(bytes.Repeat([]byte("abc"), 3)));

	//判断是否有前缀
	fmt.Println(bytes.HasPrefix([]byte("is_true"), []byte("is_")));

	//判断是否有后缀
	fmt.Println(bytes.HasSuffix([]byte("chk_on"), []byte("_on")));

	//判断是否包含某个[]byte
	fmt.Println(bytes.Contains([]byte("i am jack"), []byte("jack")));

	//判断是否包含某个rune
	fmt.Println(bytes.ContainsRune([]byte("i from 中国"), rune('中')));

	//查找sep在参数一中第一次出现的位置,找不到返回-1
	fmt.Println(bytes.Index([]byte("abcabc"), []byte("a")));
	fmt.Println(bytes.IndexByte([]byte("cba"), 'a'));
	fmt.Println(bytes.IndexRune([]byte("i from 中国"), rune('中')));

	//查找chars中任意一个字符在参数一中出现的位置,找不到返回-1
	fmt.Println(bytes.IndexAny([]byte("hello world"), "xy"));

	//功能同上,只不过查找最后一次出现的位置
	fmt.Println(bytes.LastIndex([]byte("abcabc"), []byte("a")));
	fmt.Println(bytes.LastIndexByte([]byte("cba"), 'a'));
	fmt.Println(bytes.LastIndexAny([]byte("hello world"), "xy"));

	//获取sep中在参数一中出现的次数
	fmt.Println(bytes.Count([]byte("a|b|c"), []byte("|")));

	//将参数一中前n个old替换成new,n小于0则全部替换。
	fmt.Println(string(
		bytes.Replace(
			[]byte("i am jack"),
			[]byte("i am"),
			[]byte("我是"),
			-1,
		),
	));

	//将[]byte中的字符替换为函数的返回值,如果返回值为负数,则丢弃访字符。
	fmt.Println(string(
		bytes.Map(
			func(r rune) rune {
				if r == 'a' {
					return 'A';
				} else if r == 'c' {
					return -1;
				}
				return r;
			},
			[]byte("abcd"),
		),
	));

	//将[]byte转换为[]rune
	fmt.Println(string(bytes.Runes([]byte("我是谁"))));
}

bytes中Reader和Buffer的使用:

package main;

import (
	"bytes"
	"fmt"
)

//bytes中Reader和Buffer两个结构的使用

func useReader() {
	data := "abcdefghijk";
	//通过[]byte创建Reader
	re := bytes.NewReader([]byte(data));
	//返回未读取部分的长度
	fmt.Println("re len : ", re.Len());
	//返回底层数据总长度
	fmt.Println("re size : ", re.Size());

	buf := make([]byte, 2);
	for {
		//读取数据
		n, err := re.Read(buf);
		if err != nil {
			break;
		}
		fmt.Println(string(buf[:n]));
	};

	//设置偏移量,因为上面的操作已经修改了读取位置等信息
	re.Seek(0, 0);
	for {
		//一个字节一个字节的读
		b, err := re.ReadByte();
		if err != nil {
			break;
		}
		fmt.Println(string(b));
	}

	re.Seek(0, 0);
	off := int64(0);
	for {
		//指定偏移量读取
		n, err := re.ReadAt(buf, off);
		if err != nil {
			break;
		}
		off += int64(n);
		fmt.Println(off, string(buf[:n]));
	}
}

func useBuffer() {
	data := "123456789";
	//通过[]byte创建一个Buffer
	bf := bytes.NewBuffer([]byte(data));

	//Len()返回未读取的数据长度
	fmt.Println("bf len : ", bf.Len());

	//Cap()缓存容量
	fmt.Println("bf cap : ", bf.Cap());

	//Bytes()返回未读取的数据切片
	bys := bf.Bytes();
	for _, v := range bys {
		fmt.Print(string(v) + " ");
	}
	fmt.Println();

	//Next()返回未读取部分前n字节数据的切片
	for i := 0; i < 10; i++ {
		tmp := bf.Next(1);
		fmt.Print(string(tmp) + " ");
	}
	fmt.Println();
	//再次Next,返回[]byte,说明没有未读取的
	fmt.Println(bf.Next(1));

	//重设缓冲,丢弃全部内容
	bf.Reset();

	//通过string创建Buffer
	bf2 := bytes.NewBufferString(data);
	//读取第一个 delim 及其之前的内容,返回遇到的错误
	line, _ := bf2.ReadBytes('3');
	fmt.Println(string(line));
	//效果同上,返回string
	line2, _ := bf2.ReadString('7');
	fmt.Println(line2);

	//创建一个空Buffer
	bf3 := bytes.Buffer{};
	//自动增加缓存容量,保证有n字节剩余空间
	bf3.Grow(16);
	//写入rune编码,返回写入的字节数和错误。
	n, _ := bf3.WriteRune(rune('中'));
	fmt.Println("bf3 write ", n);
	n, _ = bf3.WriteString("国人");
	fmt.Println("bf3 write ", n);
	//返回未读取的字符串
	fmt.Println(bf3.String());
	//将数据长度截断到n字节
	bf3.Truncate(6);
	fmt.Println(bf3.String());
}

func main() {
	//防止main中代码过多,我新建两个函数单独写
	useReader();
	useBuffer();
}

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!