日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Go語言標(biāo)準(zhǔn)庫bufio詳解

?01 介紹

Go 語言標(biāo)準(zhǔn)庫 bufio? 是基于 Go 語言標(biāo)準(zhǔn)庫 io? 實(shí)現(xiàn)的,查看源碼可以發(fā)現(xiàn),實(shí)際上它是包裝了 io.Reader? 接口和 io.Writer 接口,并且實(shí)現(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 錯(cuò)誤。
  • lastByte int 未讀字節(jié)的上一個(gè)字節(jié)。
  • lastRuneSize 未讀字符的上一個(gè)字符的大小。

bufio.Reader 的初始化方式:

使用 bufio.Reader? 時(shí),需要先初始化,bufio? 包提供了兩個(gè)初始化的函數(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)這兩個(gè)函數(shù)的返回值都是 *bufio.Reader 類型。

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

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

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

bufio.Reader 提供的方法:

bufio.Reader? 提供了 15 個(gè)方法,我們介紹兩個(gè)比較常用的方法,分別是 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é)大小和錯(cuò)誤。

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 的位置,并返回?cái)?shù)據(jù)和錯(cuò)誤。

使用示例:

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é)切片的長(zhǎng)度,一個(gè)中文字符是 3 個(gè)字節(jié),一個(gè)英文字符是 1 個(gè)字節(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 類型,使用單引號(hào)。

03 總結(jié)

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

實(shí)際上標(biāo)準(zhǔn)庫 bufio 使用非常簡(jiǎn)單,但是想要避免踩 “坑”,讀者朋友們最好是熟讀標(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/


名稱欄目:Go語言標(biāo)準(zhǔn)庫bufio詳解
URL地址:http://m.5511xx.com/article/ccccedp.html