国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - 詳解golang中bufio包的實現原理

詳解golang中bufio包的實現原理

2020-05-13 11:05liangwt Golang

這篇文章主要介紹了詳解golang中bufio包的實現原理,通過分析golang中bufio包的源碼,來了解為什么bufio能夠提高文件讀寫的效率和速度

bufio 包介紹 

bufio包實現了有緩沖的I/O。它包裝一個io.Reader或io.Writer接口對象,創建另一個也實現了該接口,且同時還提供了緩沖和一些文本I/O的幫助函數的對象。

以上為官方包的介紹,在其中我們能了解到的信息如下:

bufio 是通過緩沖來提高效率

簡單的說就是,把文件讀取進緩沖(內存)之后再讀取的時候就可以避免文件系統的io 從而提高速度。同理,在進行寫操作時,先把文件寫入緩沖(內存),然后由緩沖寫入文件系統。看完以上解釋有人可能會表示困惑了,直接把 內容->文件 和 內容->緩沖->文件相比, 緩沖區好像沒有起到作用嘛。其實緩沖區的設計是為了存儲多次的寫入,最后一口氣把緩沖區內容寫入文件。下面會詳細解釋

bufio 封裝了io.Reader或io.Writer接口對象,并創建另一個也實現了該接口的對象

io.Reader或io.Writer 接口實現read() 和 write() 方法,對于實現這個接口的對象都是可以使用這兩個方法的

bufio 包實現原理

詳解golang中bufio包的實現原理

bufio 源碼分析

Reader對象

bufio.Reader 是bufio中對io.Reader 的封裝

?
1
2
3
4
5
6
7
8
9
// Reader implements buffering for an io.Reader object.
type Reader struct {
  buf     []byte
  rd      io.Reader // reader provided by the client
  r, w     int    // buf read and write positions
  err     error
  lastByte   int
  lastRuneSize int
}

bufio.Read(p []byte) 相當于讀取大小len(p)的內容,思路如下:

  1. 當緩存區有內容的時,將緩存區內容全部填入p并清空緩存區

  2. 當緩存區沒有內容的時候且len(p)>len(buf),即要讀取的內容比緩存區還要大,直接去文件讀取即可

  3. 當緩存區沒有內容的時候且len(p)<len(buf),即要讀取的內容比緩存區小,緩存區從文件讀取內容充滿緩存區,并將p填滿(此時緩存區有剩余內容)

  4. 以后再次讀取時緩存區有內容,將緩存區內容全部填入p并清空緩存區(此時和情況1一樣)

以下是源碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Read reads data into p.
// It returns the number of bytes read into p.
// The bytes are taken from at most one Read on the underlying Reader,
// hence n may be less than len(p).
// At EOF, the count will be zero and err will be io.EOF.
func (b *Reader) Read(p []byte) (n int, err error) {
  n = len(p)
  if n == 0 {
    return 0, b.readErr()
  }
  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()
    }
    // One read.
    // Do not use b.fill, which will loop.
    b.r = 0
    b.w = 0
    n, b.err = b.rd.Read(b.buf)
    if n < 0 {
      panic(errNegativeRead)
    }
    if n == 0 {
      return 0, b.readErr()
    }
    b.w += n
  }
 
  // copy as much as we can
  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
}

說明:

reader內部通過維護一個r, w 即讀入和寫入的位置索引來判斷是否緩存區內容被全部讀出

Writer對象

bufio.Writer 是bufio中對io.Writer 的封裝

?
1
2
3
4
5
6
7
// Writer implements buffering for an io.Writer object.
type Writer struct {
  err error
  buf []byte
  n  int
  wr io.Writer
}

bufio.Write(p []byte) 的思路如下

  1. 判斷buf中可用容量是否可以放下 p

  2. 如果能放下,直接把p拼接到buf后面,即把內容放到緩沖區

  3. 如果緩沖區的可用容量不足以放下,且此時緩沖區是空的,直接把p寫入文件即可

  4. 如果緩沖區的可用容量不足以放下,且此時緩沖區有內容,則用p把緩沖區填滿,把緩沖區所有內容寫入文件,并清空緩沖區

  5. 判斷p的剩余內容大小能否放到緩沖區,如果能放下(此時和步驟1情況一樣)則把內容放到緩沖區

  6. 如果p的剩余內容依舊大于緩沖區,(注意此時緩沖區是空的,情況和步驟2一樣)則把p的剩余內容直接寫入文件

以下是源碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Write writes the contents of p into the buffer.
// It returns the number of bytes written.
// If nn < len(p), it also returns an error explaining
// why the write is short.
func (b *Writer) Write(p []byte) (nn int, err error) {
  for len(p) > b.Available() && b.err == nil {
    var n int
    if b.Buffered() == 0 {
      // Large write, empty buffer.
      // Write directly from p to avoid copy.
      n, b.err = b.wr.Write(p)
    } else {
      n = copy(b.buf[b.n:], p)
      b.n += n
      b.flush()
    }
    nn += n
    p = p[n:]
  }
  if b.err != nil {
    return nn, b.err
  }
  n := copy(b.buf[b.n:], p)
  b.n += n
  nn += n
  return nn, nil
}

說明:

b.wr 存儲的是一個io.writer對象,實現了Write()的接口,所以可以使用b.wr.Write(p) 將p的內容寫入文件

b.flush() 會將緩存區內容寫入文件,當所有寫入完成后,因為緩存區會存儲內容,所以需要手動flush()到文件

b.Available() 為buf可用容量,等于len(buf) - n

下圖解釋的是其中一種情況,即緩存區有內容,剩余p大于緩存區

詳解golang中bufio包的實現原理

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://my.oschina.net/liangwt/blog/1603593

延伸 · 閱讀

精彩推薦
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 91在线资源 | 欧美精品一二三区 | 天天干人人 | 日韩欧美在线视频 | 国产成人久久精品一区二区三区 | 日韩视频免费在线观看 | 天天天操 | 不卡一区二区三区视频 | 亚洲精品影院在线 | 国产精品久久久久久久久免费桃花 | 本道综合精品 | 欧美日韩亚洲成人 | 中文在线中文a | 精品一二区 | 国产精品中文字幕在线 | 精品视频一区二区三区 | 香蕉av影院| 免费国产一区二区 | 一区二区三区在线观看视频 | 一级黄色片看看 | 亚洲欧美一区二区三区情侣bbw | 黄视频在线观看免费 | www中文字幕| 亚洲视频三区 | 亚洲一区免费视频 | 日韩免费 | 成人午夜在线播放 | 欧美精品一区二区三区中文字幕 | 免费在线黄色网址 | 日韩精品一区二区三区在线观看 | 中文字幕亚洲综合久久久软件 | 超碰偷拍| 国产精品自产拍在线观看桃花 | 久久久久久久国产精品免费播放 | 国产精品美女久久久久久免费 | 成人综合视频在线 | 亚洲在线看 | 国产视频网 | 羞羞av| 亚洲a网| 中文字幕av亚洲精品一部二部 |