原文:https://www.jianshu.com/p/e53083132a25

Buffer 介绍
Buffer 是 bytes 包中的一个 type Buffer struct{…}
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.

(是一个变长的 buffer,具有 Read 和Write 方法。 Buffer 的 零值 是一个 空的 buffer,但是可以使用)
Buffer 就像一个集装箱容器,可以存东西,取东西(存取数据)

创建缓冲器

func main() {
buf1 := bytes.NewBufferString("hello")
buf2 := bytes.NewBuffer([]byte("hello"))
buf3 := bytes.NewBuffer([]byte{'h','e','l','l','o'})
fmt.Printf("%v,%v,%v\n",buf1,buf2,buf3)
fmt.Printf("%v,%v,%v\n",buf1.Bytes(),buf2.Bytes(),buf3.Bytes()) buf4 := bytes.NewBufferString("")
buf5 := bytes.NewBuffer([]byte{})
fmt.Println(buf4.Bytes(),buf5.Bytes())
}

输出

hello,hello,hello
[ ],[ ],[ ]
[] []

写入到缓冲器
buffer在new的时候是空的,也是可以直接Write的

Write

func (b *Buffer) Write(p []byte) (n int,err error)
func main() {
s := []byte(" world")
buf := bytes.NewBufferString("hello")
fmt.Printf("%v,%v\n",buf.String(),buf.Bytes())
buf.Write(s)
fmt.Printf("%v,%v\n",buf.String(),buf.Bytes())
}

结果

hello,[    ]
hello world,[ ]

WriteString

func (b *Buffer) WriteString(s string)(n int,err error)
func main() {
s := " world"
buf := bytes.NewBufferString("hello")
fmt.Printf("%v,%v\n",buf.String(),buf.Bytes())
buf.WriteString(s)
fmt.Printf("%v,%v\n",buf.String(),buf.Bytes())
}

结果

hello,[    ]
hello world,[ ]
缓冲区原理介绍
go字节缓冲区底层以字节切片做存储,切片存在长度len与容量cap, 缓冲区写从长度len的位置开始写,当len>cap时,会自动扩容。缓冲区读会从内置标记off位置开始读(off始终记录读的起始位置),当off==len时,表明缓冲区已全部读完
并重置缓冲区(len=off=0),此外当将要内容长度+已写的长度(即len) <= cap/2时,缓冲区前移覆盖掉已读的内容(off=0,len-=off),从避免缓冲区不断扩容
func main() {
byteSlice := make([]byte, )
byteSlice[] = // 将缓冲区第一个字节置1
byteBuffer := bytes.NewBuffer(byteSlice) // 创建20字节缓冲区 len = 20 off = 0
c, _ := byteBuffer.ReadByte() // off+=1
fmt.Printf("len:%d, c=%d\n", byteBuffer.Len(), c) // len = 20 off =1 打印c=1
byteBuffer.Reset() // len = 0 off = 0
fmt.Printf("len:%d\n", byteBuffer.Len()) // 打印len=0
byteBuffer.Write([]byte("hello byte buffer")) // 写缓冲区 len+=17
fmt.Printf("len:%d\n", byteBuffer.Len()) // 打印len=17
byteBuffer.Next() // 跳过4个字节 off+=4
c, _ = byteBuffer.ReadByte() // 读第5个字节 off+=1
fmt.Printf("第5个字节:%d\n", c) // 打印:111(对应字母o) len=17 off=5
byteBuffer.Truncate() // 将未字节数置为3 len=off+3=8 off=5
fmt.Printf("len:%d\n", byteBuffer.Len()) // 打印len=3为未读字节数 上面len=8是底层切片长度
byteBuffer.WriteByte() // len+=1=9 将y改成A
byteBuffer.Next() // len=9 off+=3=8
c, _ = byteBuffer.ReadByte() // off+=1=9 c=96
fmt.Printf("第9个字节:%d\n", c) // 打印:96
}
 demo1
package main

import "bytes"
import "log" func main(){
buf := &bytes.Buffer{}
buf.WriteString("abcdefg") str, _ := buf.ReadString('?')
log.Println("str = ", str)
log.Println("buff = ", buf.String())
}

输出:

[root@localhost]# go run buffer.go
// :: str = abcdefg
// :: buff =

demo2

// MyBuffer2 project main.go
package main import (
"bytes"
"log"
"os"
) func main() {
log.SetFlags(log.Lshortfile)
buff := bytes.NewBufferString("")
log.Println("buff = ", buff.String()) s := make([]byte, )
n, _ := buff.Read(s)
log.Println("buff = ", buff.String())
log.Println("s = ", string(s))
log.Println("n = ", n) n, _ = buff.Read(s)
log.Println("buff = ", buff.String())
log.Println("s = ", string(s))
log.Println("n = ", n) n, _ = buff.Read(s)
log.Println("buff = ", buff.String())
log.Println("s = ", string(s))
log.Println("n = ", n) buff.Reset()
buff.WriteString("abcdefg")
log.Println("buff = ", buff.String()) b, _ := buff.ReadByte()
log.Println("b = ", string(b))
log.Println("buff = ", buff.String()) b, _ = buff.ReadByte()
log.Println("b = ", string(b))
log.Println("buff = ", buff.String()) bs, _ := buff.ReadBytes('e')
log.Println("bs = ", string(bs))
log.Println("buff = ", buff.String()) buff.Reset()
buff.WriteString("编译输出GO")
r, l, _ := buff.ReadRune()
log.Println("r = ", r, ", l = ", l, ", string(r) = ", string(r)) buff.Reset()
buff.WriteString("qwer")
str, _ := buff.ReadString('?')
log.Println("str = ", str)
log.Println("buff = ", buff.String()) buff.WriteString("qwer")
str, _ = buff.ReadString('w')
log.Println("str = ", str)
log.Println("buff = ", buff.String()) file, _ := os.Open("doc.go")
buff.Reset()
buff.ReadFrom(file)
log.Println("doc.go = ", buff.String()) buff.Reset()
buff.WriteString("中国人")
cbyte := buff.Bytes()
log.Println("cbyte = ", cbyte)
}

输出:

C:/Go/bin/go.exe build -i [D:/golang/src/MyBuffer2]
成功: 进程退出代码 .
D:/golang/src/MyBuffer2/MyBuffer2.exe [D:/golang/src/MyBuffer2]
main.go:: buff =
main.go:: buff =
main.go:: s =
main.go:: n =
main.go:: buff =
main.go:: s =
main.go:: n =
main.go:: buff =
main.go:: s =
main.go:: n =
main.go:: buff = abcdefg
main.go:: b = a
main.go:: buff = bcdefg
main.go:: b = b
main.go:: buff = cdefg
main.go:: bs = cde
main.go:: buff = fg
main.go:: r = , l = , string(r) = 编
main.go:: str = qwer
main.go:: buff =
main.go:: str = qw
main.go:: buff = er
main.go:: doc.go = // MyBuffer2 project doc.go /*
MyBuffer2 document
*/
package main main.go:: cbyte = [ ]
成功: 进程退出代码 .

Golang bytes.buffer详解的更多相关文章

  1. 前端后台以及游戏中使用Google Protocol Buffer详解

    前端后台以及游戏中使用Google Protocol Buffer详解 0.什么是protoBuf protoBuf是一种灵活高效的独立于语言平台的结构化数据表示方法,与XML相比,protoBuf更 ...

  2. Golang Context 包详解

    Golang Context 包详解 0. 引言 在 Go 语言编写的服务器程序中,服务器通常要为每个 HTTP 请求创建一个 goroutine 以并发地处理业务.同时,这个 goroutine 也 ...

  3. java NIO Buffer 详解(1)

    1.java.io  最为核心的概念是流(stream),面向流的编程,要么输入流要么输出流,二者不可兼具: 2.java.nio 中拥有3个核心概念: Selector Channel, Buffe ...

  4. golang bytes.Buffer Reset

    func t() { a := []'} buf := new(bytes.Buffer) buf.Write(a) b := buf.Bytes() fmt.Println(b) buf.Reset ...

  5. Potocol Buffer详解

    protocol安装及使用 上一篇博文介绍了一个综合案例,这篇将详细介绍protocol buffer. 为什么使用protocol buffer? java默认序列化效率较低. apache的thr ...

  6. Protocol Buffer详解

    1.Protocol Buffer 概念 Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 ...

  7. 网卡的 Ring Buffer 详解

    1. 网卡处理数据包流程 网卡处理网络数据流程图: 图片来自参考链接1 上图中虚线步骤的解释: DMA 将 NIC 接收的数据包逐个写入 sk_buff ,一个数据包可能占用多个 sk_buff , ...

  8. Java NIO中的Buffer 详解

    Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的.缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...

  9. Golang glog使用详解

    golang/glog 是 C++ 版本 google/glog 的 Go 版本实现,基本实现了原生 glog 的日志格式.在 Kuberntes 中,glog 是默认日志库. glog 的使用与特性 ...

随机推荐

  1. 前端学习(十二):CSS排版

    进击のpython ***** 前端学习--CSS排版 本节主要介绍网页排版中主要格式化元素属性 帮助开发者把css技术与网页排版紧密联系到一起,来更好的实现网页设计效果 字体属性 字体 在日常工作中 ...

  2. PHP代码实现二分法查找

    需求:定义一个函数接收一个数组对象和一个要查找的目标元素,函数要返回该目标元素在数组中的索引值,如果目标元素不存在数组中,那么返回-1表示. //折半查找法(二分法): 使用前提必需是有序的数组. / ...

  3. socket通信的三种实现方式

    三种 socket 的实现方式 nodejs 下的 socket 服务端代码 const net = require('net') const server = net.createServer() ...

  4. c产生随机数(含时间种子)

    有时候我们需要程序产生一个随机数. 可以用rand() 但是其实这个随机数是伪随机数,它是一个周期很长的一个值而已. 所以我们可以加入一个随机数种子srand(),这个可以取以当前时间为基准的一个值. ...

  5. stringsream用法

    stringstream: 头文件: #include <sstream> 简单整理一下这玩意的作用,主要有三个吧. 类型转化 字符串拼接 字符串整合(这一个用处特别大!!!!!!!) 先 ...

  6. 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...

  7. 史蒂夫-乔布斯(Steve Jobs)斯坦福大学演讲稿(中英对照)

    这是苹果公司和Pixar动画工作室的CEO Steve Jobs于2005年6月12号在斯坦福大学的毕业典礼上面的演讲稿. Thank you. I'm honored to be with you ...

  8. JavaSwing+Mysql实现简单的登录界面+用户是否存在验证

    原生Java+mysql登录验证 client login.java 功能:实现登录页面,与服务端传来的数据验证 package LoginRegister; import java.awt.Cont ...

  9. .net core MongoDB 初试

    是这样的,我们有一个场景,另一个服务器是写到MongoDB里面,我们的MVC页面要展示,需要分页展示 自己写了一个DAL public class MongoConnect { public stri ...

  10. 【FZYZOJ】数论课堂 题解(约数个数定理)

    前言:想了两个小时orz,最后才想到要用约数个数定理…… ------------- 题目大意: 给定$n,q,A[1],A[2],A[3]$ 现有$A[i]=(A[i-1]+A[i-2]+A[i-3 ...