原文: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. Java基础-语法基础

    一.Java中的关键字和保留字 关键字:某种语言赋予了特殊含义的单词 保留字:没有赋予特殊含义,但是准备日后要使用的单词 二.Java中的标识符 其实就是在从程序中自定义的名词.比如类名.变量名,函数 ...

  2. linux 命令行 拯救萌新精简版

    装上linux 真机而不会命令行简直是太难了(这是什么人间疾苦) 于是,来几个非常基础的命令行,给(像我这样)的萌新们一点点前进的动力,也给奋斗在linux路上的大佬们一点点来自萌新的敬意吧. 一个非 ...

  3. Day12_搜索过滤

    学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"乐优商城"获取视频和教程资料! b站在线视频 0.学习 ...

  4. JVM笔记-GC常用参数设置

    GC常用参数 -Xmn -Xms -Xmx -Xss 年轻代 最小堆 最大堆 栈空间, -Xms -Xmx 一般设置成一样大小, -XX:+UseTLAB 使用TLAB,默认打开 -XX:+Print ...

  5. PHP 类型比较

    PHP 类型比较 虽然 PHP 是弱类型语言,但也需要明白变量类型及它们的意义,因为我们经常需要对 PHP 变量进行比较,包含松散和严格比较. 松散比较:使用两个等号 == 比较,只比较值,不比较类型 ...

  6. PHP filegroup() 函数

    定义和用法 filegroup() 函数返回指定文件的组 ID. 如果成功,该函数返回指定文件所属组的 ID.如果失败,则返回 FALSE. 语法 filegroup(filename) 参数 描述 ...

  7. HTML 统一资源定位器(Uniform Resource Locators)

    HTML 统一资源定位器(Uniform Resource Locators) URL 是一个网页地址.高佣联盟 www.cgewang.com URL可以由字母组成,如"runoob.co ...

  8. PHP simplexml_load_string() 函数

    实例 转换形式良好的 XML 字符串为 SimpleXMLElement 对象,然后输出对象的键和元素: <?php$note=<<<XML<note>高佣联盟 w ...

  9. linux下使用vscode和makefile搭建C++开发环境

    最近在linux上跑一些开源库做学习用, 顺手就搭了一下vscode的c++开发环境, 这里分享一下vscode进行C++开发的基本环境结构. 1. 首先是编辑器, vscode直接官网下载的, 后期 ...

  10. vue_shop(基于vue电商管理后台网站)

    vue_shop 目录 vue_shop day01 实现登录功能 项目预开发处理 Login.vue完整代码: 处理步骤: 添加element-ui的表单组件 添加第三方字体: 添加表单验证 导入a ...