Go bytes包

xxggy · · 5765 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Go bytes包

bytes包基本方法的使用

package main

import (
	"bytes"
)

func writeUInt16(buff []byte, data uint16) {
	for i := 0; i < 2; i++ {
		buff[i] = byte(data >> uint(i*8))
	}
}

func spilt(r rune) bool {
	if r == 'c' {
		return true
	}
	return false
}

func main() {
	println("hello world")
	buff1 := make([]byte, 2) // 创建一个切片
	writeUInt16(buff1, uint16(12))

	buff2 := make([]byte, 2) // 创建一个切片
	writeUInt16(buff2, uint16(12))

	// 比较两个字节数组切片
	res := bytes.Compare(buff1, buff2)
	println(res)

	// 字符串转换为字节数组
	buff3 := []byte("hello world hello world")
	seq := []byte("hello")

	// Count counts the number of non-overlapping instances of sep in s
	res = bytes.Count(buff3, seq)
	println(res)

	// Contains reports whether subslice is within b
	contains := bytes.Contains(buff3, seq) //true
	println(contains)

	res = bytes.Index(buff3, seq) // 0
	println(res)

	res = bytes.LastIndex(buff3, seq)
	println(res)

	/**
	Rune literals are just an integer value (as you've written).
	They are "mapped" to their unicode codepoint.
	 */
	a := rune('e')
	res = bytes.IndexRune(buff3, a) // -1
	println(res)

	println("------------")

	buff5 := []byte("abcabcabcabc")

	// SplitN 以 sep 为分隔符,将 s 切分成多个子串,结果中不包含 sep 本身
	// 如果 sep 为空,则将 s 切分成 Unicode 字符列表
	// 如果 s 中没有 sep,则将整个 s 作为 [][]byte 的第一个元素返回
	// 参数 n 表示最多切分出几个子串,超出的部分将不再切分
	// 如果 n 为 0,则返回 nil,如果 n 小于 0,则不限制切分个数,全部切分
	arr := bytes.SplitN(buff5, []byte("a"), 3)
	for _, v := range arr {
		for _, t := range v {
			print(t)
			print(",")
		}
		println("|")
	}

	// Fields 以连续的空白字符为分隔符,将 s 切分成多个子串,结果中不包含空白字符本身
	// 空白字符有:\t, \n, \v, \f, \r, ' ', U+0085 (NEL), U+00A0 (NBSP)
	// 如果 s 中只包含空白字符,则返回一个空列表
	println("------------")
	buff6 := []byte("abc abc abc    abc")
	arr = bytes.Fields(buff6)
	for _, v := range arr {
		for _, t := range v {
			print(t)
			print(",")
		}
		println("|")
	}

	// FieldsFunc 以一个或多个连续的满足 f(rune) 的字符为分隔符,
	// 将 s 切分成多个子串,结果中不包含分隔符本身
	// 如果 s 中没有满足 f(rune) 的字符,则返回一个空列表
	println("------------")
	buff7 := []byte("abcabcabcabc")
	arr = bytes.FieldsFunc(buff7, spilt)
	for _, v := range arr {
		for _, t := range v {
			print(t)
			print(",")
		}
		println("|")
	}

	buff8 := []byte("我是中国人")
	// 将 s 切分为 Unicode 码点列表
	data := bytes.Runes(buff8)
	for _, elem := range data {
		println(string(elem))
	}

	// Title 将 s 中的所有单词的首字母修改为其 Title 格式
	buff9 := bytes.Title(buff7)
	println(string(buff9))

	// Map 将 s 中满足 mapping(rune) 的字符替换为 mapping(rune) 的返回值
	// 如果 mapping(rune) 返回负数,则相应的字符将被删除
	buff10 := bytes.Map(func(r rune) rune {
		if r == 'c' {
			return 'a'
		}
		return r
	}, buff7)
	println(string(buff10))
}

 

bytes包结构体-bytes.Reader

reader.go文件

// A Reader implements the io.Reader, io.ReaderAt, io.WriterTo, io.Seeker,
// io.ByteScanner, and io.RuneScanner interfaces by reading from
// a byte slice.
// Unlike a Buffer, a Reader is read-only and supports seeking.
type Reader struct {
	s        []byte
	i        int64 // current reading index
	prevRune int   // index of previous rune; or < 0
}

Reader实现了以下接口,

io.Reader

io.ReaderAt 

io.WriterTo 

io.Seeker

io.ByteScanner

io.RuneScanner

Unlike a Buffer, a Reader is read-only and supports seeking.

Reader结构体所属的方法,

func NewReader(b []byte) *Reader
func (r *Reader) Len() int

// Read implements the io.Reader interface
// Read 将 len(b) 个字节读取到 b 中。
func (r *Reader) Read(b []byte) (n int, err error)

// ReadAt implements the io.ReaderAt interface 
// 从偏移量off开始读取len(b)个字节到 b 中
func (r *Reader) ReadAt(b []byte, off int64) (n int, err error)

func (r *Reader) ReadByte() (byte, error)
func (r *Reader) ReadRune() (ch rune, size int, err error)
func (r *Reader) Reset(b []byte)

// Seek implements the io.Seeker interface.
func (r *Reader) Seek(offset int64, whence int) (int64, error)
func (r *Reader) Size() int64

// UnreadByte implements the io.ByteScanner interface
func (r *Reader) UnreadByte() error

// UnreadRune implements the io.RuneScanner interface
func (r *Reader) UnreadRune() error

// WriteTo implements the io.WriteTo interface
// WriteTo writes data to w until there's no more data to write or
// when an error occurs.
func (r *Reader) WriteTo(w io.Writer) (n int64, err error)

方法的使用示例,

package main

import (
	"bytes"
	"fmt"
	"io"
)

func main() {

	b1 := []byte("Hello World!")
	reader := bytes.NewReader(b1)

	// Read 方法
	buff := make([]byte, 5)
	count, err := reader.Read(buff)
	if err != nil {
		return
	}
	fmt.Printf("read count = %d,read data = %s\n", count, string(buff))

	// ReadAt 方法
	buff2 := make([]byte, 5)
	count, err = reader.ReadAt(buff2, 6)
	if err != nil {
		return
	}
	fmt.Printf("read count = %d,read data = %s\n", count, string(buff2))

	for {
		// 依次返回未被读取的字节
		b, err := reader.ReadByte()
		if err == io.EOF {
			break
		}
		println(string(b))
	}

	println("--------")

	b2 := []byte("hello 世界!")

	reader2 := bytes.NewReader(b2)
	for {
		// 依次返回未被读取的rune
		r, _, err := reader2.ReadRune()
		if err == io.EOF {
			break
		}
		println(string(r))
	}

	b3 := []byte("string builder")
	// Reset resets the Reader to be reading from b.
	reader2.Reset(b3)
	println(reader2.Len())

	println("--------")

	reader3 := bytes.NewReader(b1)
	// Seek 设置下一次 Read 或 Write 的偏移量为 offset,它的解释取决于 whence:
	// 0 表示相对于文件的起始处,1 表示相对于当前的偏移,而 2 表示相对于其结尾处。
	// Seek 返回新的偏移量和一个错误,如果有的话。
	abs, err := reader3.Seek(-2, 2)
	println(abs)
	b, _ := reader3.ReadByte()
	println(string(b))
}

 

bytes包结构体-bytes.Buffer

buffer.go文件,

// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {
	buf       []byte            // contents are the bytes buf[off : len(buf)]
	off       int               // read at &buf[off], write at &buf[len(buf)]
	runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each call to WriteRune
	bootstrap [64]byte          // memory to hold first slice; helps small buffers avoid allocation.
	lastRead  readOp            // last read operation, so that Unread* can work correctly.
}

Buffer结构体所属的方法,

func NewBuffer(buf []byte) *Buffer
func NewBufferString(s string) *Buffer
func (b *Buffer) Bytes() []byte
func (b *Buffer) Cap() int
func (b *Buffer) Grow(n int)
func (b *Buffer) Len() int
func (b *Buffer) Next(n int) []byte
func (b *Buffer) Read(p []byte) (n int, err error)
func (b *Buffer) ReadByte() (byte, error)
func (b *Buffer) ReadBytes(delim byte) (line []byte, err error)
func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error)
func (b *Buffer) ReadRune() (r rune, size int, err error)
func (b *Buffer) ReadString(delim byte) (line string, err error)
func (b *Buffer) Reset()
func (b *Buffer) String() string
func (b *Buffer) Truncate(n int)
func (b *Buffer) UnreadByte() error
func (b *Buffer) UnreadRune() error
func (b *Buffer) Write(p []byte) (n int, err error)
func (b *Buffer) WriteByte(c byte) error
func (b *Buffer) WriteRune(r rune) (n int, err error)
func (b *Buffer) WriteString(s string) (n int, err error)
func (b *Buffer) WriteTo(w io.Writer) (n int64, err error)

方法的使用示例,

package main

import (
	"bytes"
	"fmt"
)

func main() {

	b1 := []byte("hello world!")
	buf := bytes.NewBuffer(b1)
	fmt.Printf("buff len=%d\n", buf.Len())
	fmt.Printf("buff cap=%d\n", buf.Cap())

	buf.Grow(100)
	fmt.Printf("buff len=%d\n", buf.Len())
	fmt.Printf("buff cap=%d\n", buf.Cap())

	b2 := make([]byte, 6)
	// Read reads the next len(p) bytes from the buffer or until the buffer is drained. The return value n is the number of bytes read.
	// If the buffer has no data to return, err is io.EOF (unless len(p) is zero); otherwise it is nil.
	buf.Read(b2)
	println(string(b2)) //hello

	b3 := buf.Next(5)
	println(string(b3)) //world

	b4 := buf.Next(3)
	println(string(b4))

	buf2 := bytes.NewBuffer(b1)
	// ReadBytes reads until the first occurrence of delim in the input,
	// returning a slice containing the data up to and including the delimiter.
	b5, _ := buf2.ReadBytes(byte(' '))
	println(len(b5))
	println(string(b5))

	b6 := []byte("go programming")
	buf3 := bytes.NewBuffer(b1)
	// Write appends the contents of p to the buffer, growing the buffer as
	// needed.
	buf3.Write(b6)
	println(string(buf3.Bytes()))
}

=======END=======


有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:xxggy

查看原文:Go bytes包

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

5765 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传