欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言的IO庫那么多糾結(jié)該如何選擇

 更新時間:2021年06月23日 14:18:14   投稿:mrr  
在Go語言中涉及 I/O 操作的內(nèi)置庫有很多種,比如: io 庫, os 庫, ioutil 庫, bufio 庫, bytes 庫, strings 庫等等。擁有這么多內(nèi)置庫是好事,但是具體到涉及 I/O 的場景我們應(yīng)該選擇哪個庫呢,帶著這個問題一起通過本文學(xué)習(xí)下吧

在計算機和信息技術(shù)領(lǐng)域里 I/O 這個術(shù)語表示輸入 / 輸出 ( 英語:Input / Output ) ,通常指數(shù)據(jù)在存儲器(內(nèi)部和外部)或其他周邊設(shè)備之間的輸入和輸出,是信息處理系統(tǒng)與外部之間的通信。輸入是系統(tǒng)接收的信號或數(shù)據(jù),輸出則是從其發(fā)送的信號或數(shù)據(jù)。

在Go語言中涉及 I/O 操作的內(nèi)置庫有很多種,比如: io 庫, os 庫, ioutil 庫, bufio 庫, bytes 庫, strings 庫等等。擁有這么多內(nèi)置庫是好事,但是具體到涉及 I/O 的場景我們應(yīng)該選擇哪個庫呢?

io.Reader/Writer

Go語言里使用 io.Reader 和 io.Writer 兩個 interface 來抽象 I/O ,他們的定義如下。

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

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

io.Reader 接口代表一個可以從中讀取字節(jié)流的實體,而 io.Writer 則代表一個可以向其寫入字節(jié)流的實體。

  • io.Reader/Writer 常用的幾種實現(xiàn)
  • net.Conn: 表示網(wǎng)絡(luò)連接。
  • os.Stdin, os.Stdout, os.Stderr: 標(biāo)準(zhǔn)輸入、輸出和錯誤。
  • os.File: 網(wǎng)絡(luò),標(biāo)準(zhǔn)輸入輸出,文件的流讀取。
  • strings.Reader: 字符串抽象成 io.Reader 的實現(xiàn)。
  • bytes.Reader: []byte抽象成 io.Reader 的實現(xiàn)。
  • bytes.Buffer: []byte抽象成 io.Reader 和 io.Writer 的實現(xiàn)。
  • bufio.Reader/Writer: 抽帶緩沖的流讀取和寫入(比如按行讀寫)。

除了這幾種實現(xiàn)外常用的還有 ioutil 工具庫包含了很多IO工具函數(shù),編碼相關(guān)的內(nèi)置庫 encoding/base64 、 encoding/binary 等也是通過 io.Reader 和 io.Writer 實現(xiàn)各自的編碼功能的。

這些常用實現(xiàn)和工具庫與io.Reader和io.Writer間的關(guān)系可以用下圖表示。

每種I/O庫的使用場景

io庫

io 庫屬于底層接口定義庫。它的作用主要是定義個 I/O 的基本接口和個基本常量,并解釋這些接口的功能。在實際編寫代碼做 I/O 操作時,這個庫一般只用來調(diào)用它的常量和接口定義,比如用 io.EOF 判斷是否已經(jīng)讀取完,用 io.Reader 做變量的類型聲明。

// 字節(jié)流讀取完后,會返回io.EOF這個error
for {
 n, err := r.Read(buf)
 fmt.Println(n, err, buf[:n])
 if err == io.EOF {
  break
 }
}

os 庫

os 庫主要是處理操作系統(tǒng)操作的,它作為Go程序和操作系統(tǒng)交互的橋梁。創(chuàng)建文件、打開或者關(guān)閉文件、Socket等等這些操作和都是和操作系統(tǒng)掛鉤的,所以都通過 os 庫來執(zhí)行。這個庫經(jīng)常和 ioutil , bufio 等配合使用

ioutil庫

ioutil 庫是一個有工具包,它提供了很多使用的 IO 工具函數(shù),例如 ReadAll、ReadFile、WriteFile、ReadDir。唯一需要注意的是它們都是一次性讀取和一次性寫入,所以使用時,尤其是把數(shù)據(jù)從文件里一次性讀到內(nèi)存中時需要注意文件的大小。

讀出文件中的所有內(nèi)容

func readByFile() {
  data, err := ioutil.ReadFile( "./file/test.txt")
  if err != nil {
    log.Fatal("err:", err)
    return
  }
  fmt.Println("data", string(data)) 
}

將數(shù)據(jù)一次性寫入文件

func writeFile() {
  err := ioutil.WriteFile("./file/write_test.txt", []byte("hello world!"), 0644)
  if err != nil {
    panic(err)
    return
  }
}

bufio庫

bufio,可以理解為在 io 庫的基礎(chǔ)上額外封裝加了一個緩存層,它提供了很多按行進行讀寫的函數(shù),從io庫的按字節(jié)讀寫變?yōu)榘葱凶x寫對寫代碼來說還是方便了不少。

func readBigFile(filePath string) error {
  f, err := os.Open(filePath)
  defer f.Close()

  if err != nil {
    log.Fatal(err)
    return err
  }

  buf := bufio.NewReader(f)
  count := 0
  // 循環(huán)中打印前100行內(nèi)容
  for {
    count += 1
    line, err := buf.ReadString('\n')
    line = strings.TrimSpace(line)
    if err != nil {
      return err
    }
    fmt.Println("line", line)

    if count > 100 {
      break
    }
  }
  return nil
}

  • ReadLine和ReadString方法:buf.ReadLine(),buf.ReadString("\n")都是按行讀,只不過ReadLine讀出來的是[]byte,后者直接讀出了string,最終他們底層調(diào)用的都是ReadSlice方法。
  • bufio VS ioutil 庫:bufio VS 和 ioutil 庫都提供了讀寫文件的能力。它們之間唯一的區(qū)別是 bufio 有一個額外的緩存層。這個優(yōu)勢主要體現(xiàn)在讀取大文件的時候。

bytes 和 strings 庫

bytes 和 strings 庫里的 bytes.Reader 和string.Reader,它們都實現(xiàn)了 io.Reader 接口,也都提供了NewReader方法用來從 []byte 或者 string 類型的變量直接構(gòu)建出相應(yīng)的Reader實現(xiàn)。

r := strings.NewReader("abcde")
// 或者是 bytes.NewReader([]byte("abcde"))
buf := make([]byte, 4)
for {
 n, err := r.Read(buf)
 fmt.Println(n, err, buf[:n])
 if err == io.EOF {
  break
 }
}

另一個區(qū)別是 bytes 庫有Buffer的功能,而 strings 庫則沒有。

var buf bytes.Buffer
fmt.Fprintf(&buf, "Size: %d MB.", 85)
s := buf.String()) // s == "Size: 85 MB."

總結(jié)

關(guān)于 io.Reader 和 io.Writer 接口,可以簡單理解為讀源和寫源。也就是說,只要實現(xiàn)了 Reader 中的 Read 方法,這個東西就可以作為讀源,里面可以包含數(shù)據(jù),被我們讀取。 Writer 也是如此。

以上是我對Go語言里做 I/O 操作時經(jīng)常會用到的Go語言內(nèi)置庫在使用場景和每個庫要解決的問題上的一些總結(jié),希望能幫大家理清思路,作為參考,在開發(fā)任務(wù)中需要時正確選擇合適的庫完成 I/O 操作。如果文章中的敘述有錯誤,歡迎留言指正,也歡迎在留言中對文章內(nèi)容進行探討和提出建議。

以上就是Go語言的IO庫那么多糾結(jié)該如何選擇的詳細(xì)內(nèi)容,更多關(guān)于Go語言IO庫的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語言讀取YAML 配置文件的兩種方式分享

    Go語言讀取YAML 配置文件的兩種方式分享

    在日常開發(fā)中,YAML 格式的文件基本上被默認(rèn)為是配置文件,其內(nèi)容因為縮進帶來的層級感看起來非常直觀和整潔。本文分享了讀取YAML 配置文件的兩種方式,需要的可以參考一下
    2022-12-12
  • Go語言清除文件中空行的方法

    Go語言清除文件中空行的方法

    這篇文章主要介紹了Go語言清除文件中空行的方法,實例分析了Go語言針對文件的操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • golang的協(xié)程上下文的具體使用

    golang的協(xié)程上下文的具體使用

    golang的context?主要用來在?goroutine?之間傳遞上下文信息,包括:取消信號、超時時間、截止時間、k-v?等,本文就詳細(xì)的來介紹一下golang的協(xié)程上下文的具體使用,感興趣的可以了解一下
    2022-04-04
  • 幾個小技巧幫你實現(xiàn)Golang永久阻塞

    幾個小技巧幫你實現(xiàn)Golang永久阻塞

    Go 的運行時的當(dāng)前設(shè)計,假定程序員自己負(fù)責(zé)檢測何時終止一個 goroutine 以及何時終止該程序。有時候我們需要的是使程序阻塞在這一行,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-12-12
  • golang實現(xiàn)ip訪問限制及提交次數(shù)

    golang實現(xiàn)ip訪問限制及提交次數(shù)

    在?Web?應(yīng)用中,通常會需要對?IP?訪問進行限制以及控制提交次數(shù),本文將使用中間件或者基于?Redis?這樣的緩存服務(wù)來實現(xiàn),感興趣的可以了解下
    2024-10-10
  • Golang中下劃線(_)的不錯用法分享

    Golang中下劃線(_)的不錯用法分享

    golang中的下劃線表示忽略變量的意思,也沒有產(chǎn)生新的變量,但是后面的表達(dá)式依然會被執(zhí)行,本文為大家整理了golang中下劃線的一些不錯的用法,需要的可以參考下
    2023-05-05
  • golang多維度排序及題解最長連續(xù)序列

    golang多維度排序及題解最長連續(xù)序列

    這篇文章主要為大家介紹了golang多維度排序及題解最長連續(xù)序列示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • Golang 實現(xiàn) Redis系列(六)如何實現(xiàn) pipeline 模式的 redis 客戶端

    Golang 實現(xiàn) Redis系列(六)如何實現(xiàn) pipeline 模式的 redis 客戶端

    pipeline 模式的 redis 客戶端需要有兩個后臺協(xié)程負(fù)責(zé) tcp 通信,調(diào)用方通過 channel 向后臺協(xié)程發(fā)送指令,并阻塞等待直到收到響應(yīng),本文是使用 golang 實現(xiàn) redis 系列的第六篇, 將介紹如何實現(xiàn)一個 Pipeline 模式的 Redis 客戶端。
    2021-07-07
  • Go語言sync包與鎖實現(xiàn)限制線程對變量的訪問

    Go語言sync包與鎖實現(xiàn)限制線程對變量的訪問

    本文主要介紹了Go語言sync包與鎖實現(xiàn)限制線程對變量的訪問,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 在 Golang 中實現(xiàn) Cache::remember 方法詳解

    在 Golang 中實現(xiàn) Cache::remember 方法詳解

    這篇文章主要介紹了在 Golang 中實現(xiàn) Cache::remember 方法詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03

最新評論