關於golang中IO相關的Buffer類淺析


io重要的接口

在介紹buffer之前,先來認識兩個重要的接口,如下邊所示:

type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

  

上邊兩個接口在golang sdk安裝目錄src/io/io.go中定義。后邊凡是涉及到io相關操作的,基本上都實現了這兩個接口,如:

1. package bufio 中的Reader類
2. package bytes 中的Reader類與Buffer類
3. package os 中 的File類,這個實現的最為復雜,主要由於在文件操作中,需要系統底層提供服務。
...不再一一列舉...

  

經常聽說有這么一句話:“使用I/O buffer,有助於提高效率”。但是,我想反問的是,真的提高了效率了嗎? 
buffer在什么情況下會提高我們的程序性能呢?帶着這個問題,我們來剖析一下上邊提到的幾個類。

1.第一個類bytes.Reader

這個類,實現了io.Reader接口,但是這個類沒有實現io.Writer接口。這個類沒有buffer,為啥?因為這個類,在初始化時,將字符流傳入到對象中保存,沒有提供Write方法寫入新的字符流。所以,這個類不需要buffer。

2.第二個類bytes.Buffer

這個類實現了io.Reader與io.Writer接口,這個類在寫入字節流的過程中,使用到了buffer,怎么實現的呢? 
在初始化這個類時,會傳入一個[]byte類型的slice到對象中,當Write方法向這個對象中寫入字節流時,如果之前傳入的這個[]byte申請的空間不夠時,Write會調用自身的Grow方法,給這個[]byte類型的slice類型擴容,這樣,這個里邊的buffer會隨着寫入量增大,長度會不斷的擴大。如果此處沒有buffer的話,當寫入容量滿時,要么阻塞,要么循環寫入,這樣會導致系統卡死或數據被破壞,當引入buffer后,解決了上邊的兩個問題。但是這種解決方式,存在一個隱患,也就是如果出現讀取死循環,這樣會造成內存溢出。

3.第三個類bufio.Reader

這個類實現了io.Reader接口,這個類在實例化時,需要傳入一個io.Reader類型的變量,這問題就來了,一個io.Reader類型的變量,一定是實現了Read方法了,那么為什么還需要裝進bufio.Reader對象中呢?原來,bufio.Reader類中得Read方法,在讀取字節流時,對傳入的[]byte類型變量空間長度進行檢查,如果傳入變量的長度小於bufio.Reader初始化的容量,將會首先調用io.Reader自己的Read方法,將內容寫入到bufio.Reader對象的buffer中,然后將值復制給傳入的[]byte變量。這樣做的好處是,在執行io.Reader的Read方法時,多讀取一些字節,這樣對於像文件操作就大有裨益。

4.第四個類os.File

這個類實現了io.Writer與io.Reader類,但是有點特殊的是,os.File的Read方法與Write均需要借助於系統層面的文件操作方法.總所周知,在文件讀取時,Read與Write方法時沒有緩存的,也就是你讀幾個字節,取決於你傳入的變量容量是多少,如果容量為1,那么對於文件讀取而言,就會很慢,所以將os.File的對象,傳入到bufio.Reader對象中,這樣可以在某些程度上提高效率,哪些時候呢?就是你在調用Read方法時,傳入的變量容量太小時,會提高讀取效率.但是bufio.Reader提供的Read方法不能保證每次讀到的字符數一致,這個與其實現方式有關,但是不影響我們使用,只要確保收到EOF,再停止讀取即可.

總結 
在使用I/O操作時,bufio包提供了帶buffer的方式讀取I/O流,在操作文件讀取,報文讀取等上,可以在某種程度上提高效率,bufio中的類,並沒有從底層實現Read與Write方法,只是限定了最小讀取量.這個最小量就是bufio.Reader初始化長度. 
bytes.Buffer提供的buffer十分強大,這個類不僅實現了io.Reader接口,還實現了io.Writer接口.所以bytes.Buffer的對象不僅可以讀取,還可以追加寫入,寫入的過程中,容量還可以自動擴展,所以,功能十分強大.但是在使用時,要注意安全,bytes.Buffer會不斷的擴大,擴大,最終還會panic.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM