自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go 語言標(biāo)準(zhǔn)庫 bufio 詳解

開發(fā) 前端
本文我們以 bufio.Reader 為例,介紹標(biāo)準(zhǔn)庫 bufio 的數(shù)據(jù)類型、初始化方式和提供的方法。

?01 介紹

Go 語言標(biāo)準(zhǔn)庫 bufio? 是基于 Go 語言標(biāo)準(zhǔn)庫 io? 實現(xiàn)的,查看源碼可以發(fā)現(xiàn),實際上它是包裝了 io.Reader? 接口和 io.Writer 接口,并且實現(xiàn)它們。

bufio 顧名思義,就是在緩沖區(qū)讀寫數(shù)據(jù),比直接讀寫文件或網(wǎng)絡(luò)中的數(shù)據(jù),性能更好些。

本文我們介紹 bufio? 的相關(guān)內(nèi)容,建議讀者朋友們最好是先了解一下 io 的相關(guān)內(nèi)容。

02 標(biāo)準(zhǔn)庫 bufio 的數(shù)據(jù)類型

查看標(biāo)準(zhǔn)庫 `bufio` 的文檔[1],它的數(shù)據(jù)類型主要有 bufio.Reader、bufio.Writer、bufio.ReadWriter? 和 bufio.Scanner。

我們以 bufio.Reader 為例,介紹它的數(shù)據(jù)結(jié)構(gòu)、初始化方式和提供的方法。

bufio.Reader 的數(shù)據(jù)結(jié)構(gòu):

type Reader struct {
buf []byte
rd io.Reader
r, w int
err error
lastByte int
lastRuneSize int
}

閱讀源碼,我們可以發(fā)現(xiàn) bufio.Reader 中包含的字段:

  • buf []byte 緩沖區(qū)。
  • rd io.Reader 緩沖區(qū)的數(shù)據(jù)源。
  • r,w int 緩沖區(qū)讀寫索引位置。
  • err error 錯誤。
  • lastByte int 未讀字節(jié)的上一個字節(jié)。
  • lastRuneSize 未讀字符的上一個字符的大小。

bufio.Reader 的初始化方式:

使用 bufio.Reader? 時,需要先初始化,bufio? 包提供了兩個初始化的函數(shù),分別是 NewReaderSize? 和 NewReader。

func NewReaderSize(rd io.Reader, size int) *Reader {
// Is it already a Reader?
b, ok := rd.(*Reader)
if ok && len(b.buf) >= size {
return b
}
if size < minReadBufferSize {
size = minReadBufferSize
}
r := new(Reader)
r.reset(make([]byte, size), rd)
return r
}

func NewReader(rd io.Reader) *Reader {
return NewReaderSize(rd, defaultBufSize)
}

閱讀源碼,我們可以發(fā)現(xiàn)這兩個函數(shù)的返回值都是 *bufio.Reader 類型。

其中 NewReader? 是包裝了 NewReaderSize 函數(shù),給定了一個默認(rèn)值 4096,設(shè)置讀緩沖區(qū)的大小。

如果我們使用默認(rèn)值,一般選擇使用 NewReader 函數(shù)。

如果不想使用默認(rèn)值,可以選擇使用 NewReaderSize 函數(shù)。

bufio.Reader 提供的方法:

bufio.Reader? 提供了 15 個方法,我們介紹兩個比較常用的方法,分別是 Read? 和 ReadBytes。

func (b *Reader) Read(p []byte) (n int, err error) {
// 省略代碼 ...
if b.r == b.w {
if b.err != nil {
return 0, b.readErr()
}
if len(p) >= len(b.buf) {
// Large read, empty buffer.
// Read directly into p to avoid copy.
n, b.err = b.rd.Read(p)
if n < 0 {
panic(errNegativeRead)
}
if n > 0 {
b.lastByte = int(p[n-1])
b.lastRuneSize = -1
}
return n, b.readErr()
}
// 省略代碼 ...
b.w += n
}

// copy as much as we can
// Note: if the slice panics here, it is probably because
// the underlying reader returned a bad count. See issue 49795.
n = copy(p, b.buf[b.r:b.w])
b.r += n
b.lastByte = int(b.buf[b.r-1])
b.lastRuneSize = -1
return n, nil
}

閱讀源碼,我們可以發(fā)現(xiàn) Read? 方法是將緩沖區(qū)中的數(shù)據(jù),讀取到 p 中,并返回讀取的字節(jié)大小和錯誤。

func (b *Reader) ReadBytes(delim byte) ([]byte, error) {
full, frag, n, err := b.collectFragments(delim)
// Allocate new buffer to hold the full pieces and the fragment.
buf := make([]byte, n)
n = 0
// Copy full pieces and fragment in.
for i := range full {
n += copy(buf[n:], full[i])
}
copy(buf[n:], frag)
return buf, err
}

閱讀源碼,我們可以發(fā)現(xiàn) ReadBytes? 方法是讀取緩沖區(qū)中的數(shù)據(jù)截止到分隔符 delim 的位置,并返回數(shù)據(jù)和錯誤。

使用示例:

Read 方法

func main() {
f, _ := os.Open("/Users/frank/GolandProjects/go-package/lesson14/file.txt")
defer f.Close()
r := bufio.NewReader(f)
p := make([]byte, 12)
index, _ := r.Read(p)
fmt.Println(index)
fmt.Println(string(p[:index]))
}

需要注意的是,p 字節(jié)切片的長度,一個中文字符是 3 個字節(jié),一個英文字符是 1 個字節(jié)。

ReadBytes 方法

func main() {
f, _ := os.Open("/Users/frank/GolandProjects/go-package/lesson14/file.txt")
defer f.Close()
r := bufio.NewReader(f)
bs, _ := r.ReadBytes('\n')
fmt.Println(string(bs))
}

需要注意的是,分隔符參數(shù)是 byte 類型,使用單引號。

03 總結(jié)

本文我們以 bufio.Reader? 為例,介紹標(biāo)準(zhǔn)庫 bufio 的數(shù)據(jù)類型、初始化方式和提供的方法。

實際上標(biāo)準(zhǔn)庫 bufio 使用非常簡單,但是想要避免踩 “坑”,讀者朋友們最好是熟讀標(biāo)準(zhǔn)庫 `bufio` 的源碼[2]。

參考資料

[1]標(biāo)準(zhǔn)庫 bufio? 的文檔: https://pkg.go.dev/bufio@go1.20.2

[2]標(biāo)準(zhǔn)庫 bufio? 的源碼: https://cs.opensource.google/go/go/+/refs/tags/go1.20.2:src/bufio/

責(zé)任編輯:武曉燕 來源: Golang語言開發(fā)棧
相關(guān)推薦

2023-09-07 07:35:54

GolangBufio

2023-10-07 09:08:32

Golangbufio

2023-10-10 08:57:44

Golangbufio

2023-09-27 08:26:48

Go標(biāo)準(zhǔn)庫函數(shù)

2014-01-14 09:10:53

GoHTTP內(nèi)存泄漏

2021-10-18 10:53:26

Go 代碼技術(shù)

2023-02-10 09:40:36

Go語言并發(fā)

2024-10-28 00:40:49

Go語法版本

2021-08-13 12:05:15

Goneturl

2023-10-18 08:22:38

BufioGolang

2023-04-09 23:09:59

Go語言函數(shù)

2024-05-10 08:04:44

開發(fā)者Go語言

2021-02-06 18:19:54

TimeGo語言

2020-02-11 09:41:02

Go語言程序員文章

2020-02-05 16:55:11

Go語言程序員文章

2024-07-11 08:50:05

Go語言errors

2024-09-29 16:04:14

2023-10-07 00:10:27

日志格式函數(shù)

2021-12-10 15:22:26

Go Zip 文件

2023-02-13 00:24:37

Go語言日志庫
點贊
收藏

51CTO技術(shù)棧公眾號