golang byte 转writer_聊聊golang的zap的buffer

本文主要研究一下golang的zap的buffer

b397dbb3e3d363d2bb64373ca4475d77.png

buffer

zap@v1.16.0/buffer/buffer.go

package buffer // import "go.uber.org/zap/buffer"import (    "strconv"    "time")const _size = 1024 // by default, create 1 KiB buffers// Buffer is a thin wrapper around a byte slice. It's intended to be pooled, so// the only way to construct one is via a Pool.type Buffer struct {    bs   []byte    pool Pool}// AppendByte writes a single byte to the Buffer.func (b *Buffer) AppendByte(v byte) {    b.bs = append(b.bs, v)}// AppendString writes a string to the Buffer.func (b *Buffer) AppendString(s string) {    b.bs = append(b.bs, s...)}// AppendInt appends an integer to the underlying buffer (assuming base 10).func (b *Buffer) AppendInt(i int64) {    b.bs = strconv.AppendInt(b.bs, i, 10)}// AppendTime appends the time formatted using the specified layout.func (b *Buffer) AppendTime(t time.Time, layout string) {    b.bs = t.AppendFormat(b.bs, layout)}// AppendUint appends an unsigned integer to the underlying buffer (assuming// base 10).func (b *Buffer) AppendUint(i uint64) {    b.bs = strconv.AppendUint(b.bs, i, 10)}// AppendBool appends a bool to the underlying buffer.func (b *Buffer) AppendBool(v bool) {    b.bs = strconv.AppendBool(b.bs, v)}// AppendFloat appends a float to the underlying buffer. It doesn't quote NaN// or +/- Inf.func (b *Buffer) AppendFloat(f float64, bitSize int) {    b.bs = strconv.AppendFloat(b.bs, f, 'f', -1, bitSize)}// Len returns the length of the underlying byte slice.func (b *Buffer) Len() int {    return len(b.bs)}// Cap returns the capacity of the underlying byte slice.func (b *Buffer) Cap() int {    return cap(b.bs)}// Bytes returns a mutable reference to the underlying byte slice.func (b *Buffer) Bytes() []byte {    return b.bs}// String returns a string copy of the underlying byte slice.func (b *Buffer) String() string {    return string(b.bs)}// Reset resets the underlying byte slice. Subsequent writes re-use the slice's// backing array.func (b *Buffer) Reset() {    b.bs = b.bs[:0]}// Write implements io.Writer.func (b *Buffer) Write(bs []byte) (int, error) {    b.bs = append(b.bs, bs...)    return len(bs), nil}// TrimNewline trims any final "" byte from the end of the buffer.func (b *Buffer) TrimNewline() {    if i := len(b.bs) - 1; i >= 0 {        if b.bs[i] == '' {            b.bs = b.bs[:i]        }    }}// Free returns the Buffer to its Pool. Callers must not retain references to the Buffer after calling Free.func (b *Buffer) Free() {    b.pool.put(b)}

Buffer定义了[]byte及Pool属性,它提供了AppendByte、AppendString、AppendInt、AppendTime、AppendUint、AppendBool、AppendFloat、String、Reset、Write、TrimNewline、Free方法

pool

zap@v1.16.0/buffer/pool.go

package bufferimport "sync"// A Pool is a type-safe wrapper around a sync.Pool.type Pool struct {    p *sync.Pool}// NewPool constructs a new Pool.func NewPool() Pool {    return Pool{p: &sync.Pool{        New: func() interface{} {            return &Buffer{bs: make([]byte, 0, _size)}        },    }}}// Get retrieves a Buffer from the pool, creating one if necessary.func (p Pool) Get() *Buffer {    buf := p.p.Get().(*Buffer)    buf.Reset()    buf.pool = p    return buf}func (p Pool) put(buf *Buffer) {    p.p.Put(buf)}

Pool定义了*sync.Pool属性,其NewPool方法创建sync.Pool,New方法为创建Buffer,_size默认为1024即1KB;其Get方法从pool获取buffer,其put方法用于将buffer归还到pool;由于归还时buffer可能没有reset,所以每次Get的时候都会先Reset一下再返回

bufferpool

zap@v1.16.0/internal/bufferpool/bufferpool.go

package bufferpoolimport "go.uber.org/zap/buffer"var (    _pool = buffer.NewPool()    // Get retrieves a buffer from the pool, creating one if necessary.    Get = _pool.Get)

bufferpool包创建了一个全局的_pool,并定义了Get func

FullPath

zap@v1.16.0/zapcore/entry.go

func (ec EntryCaller) FullPath() string {    if !ec.Defined {        return "undefined"    }    buf := bufferpool.Get()    buf.AppendString(ec.File)    buf.AppendByte(':')    buf.AppendInt(int64(ec.Line))    caller := buf.String()    buf.Free()    return caller}

FullPath方法使用bufferpool来创建caller

newJSONEncoder

zap@v1.16.0/zapcore/json_encoder.go

func newJSONEncoder(cfg EncoderConfig, spaced bool) *jsonEncoder {    return &jsonEncoder{        EncoderConfig: &cfg,        buf:           bufferpool.Get(),        spaced:        spaced,    }}

newJSONEncoder使用bufferpool.Get()来获取buffer,然后创建jsonEncoder

实例

func bufferDemo() {    buf := buffer.NewPool().Get()    buf.AppendByte('v')    fmt.Println(buf.String())    buf.Reset()    buf.AppendString("foo")    fmt.Println(buf.String())    buf.Reset()    buf.AppendInt(42)    fmt.Println(buf.String())    buf.Reset()    buf.AppendUint(42)    fmt.Println(buf.String())    buf.Reset()    buf.AppendBool(true)    fmt.Println(buf.String())    buf.Reset()    buf.AppendFloat(3.14, 32)    fmt.Println(buf.String())    buf.Reset()    buf.Write([]byte("foo"))    fmt.Println(buf.String())    buf.Reset()    buf.AppendTime(time.Date(2000, 1, 2, 3, 4, 5, 6, time.UTC), time.RFC3339)    fmt.Println(buf.String())    buf.Reset()    buf.Free()}

输出

vfoo4242true3.14foo2000-01-02T03:04:05Z

小结

Buffer定义了[]byte及Pool属性,它提供了AppendByte、AppendString、AppendInt、AppendTime、AppendUint、AppendBool、AppendFloat、String、Reset、Write、TrimNewline、Free方法;Pool定义了*sync.Pool属性,其NewPool方法创建sync.Pool,New方法为创建Buffer,_size默认为1024即1KB;其Get方法从pool获取buffer,其put方法用于将buffer归还到pool;由于归还时buffer可能没有reset,所以每次Get的时候都会先Reset一下再返回

doc

  • zap
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值