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

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

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

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

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

io.Reader/Writer

Go語(yǔ)言里使用 io.Reader 和 io.Writer 兩個(gè) interface 來(lái)抽象 I/O ,他們的定義如下。

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

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

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

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

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

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

每種I/O庫(kù)的使用場(chǎng)景

io庫(kù)

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

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

os 庫(kù)

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

ioutil庫(kù)

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

讀出文件中的所有內(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ù)一次性寫(xiě)入文件

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

bufio庫(kù)

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

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")都是按行讀,只不過(guò)ReadLine讀出來(lái)的是[]byte,后者直接讀出了string,最終他們底層調(diào)用的都是ReadSlice方法。
  • bufio VS ioutil 庫(kù):bufio VS 和 ioutil 庫(kù)都提供了讀寫(xiě)文件的能力。它們之間唯一的區(qū)別是 bufio 有一個(gè)額外的緩存層。這個(gè)優(yōu)勢(shì)主要體現(xiàn)在讀取大文件的時(shí)候。

bytes 和 strings 庫(kù)

bytes 和 strings 庫(kù)里的 bytes.Reader 和string.Reader,它們都實(shí)現(xiàn)了 io.Reader 接口,也都提供了NewReader方法用來(lái)從 []byte 或者 string 類(lèi)型的變量直接構(gòu)建出相應(yīng)的Reader實(shí)現(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
 }
}

另一個(gè)區(qū)別是 bytes 庫(kù)有Buffer的功能,而 strings 庫(kù)則沒(méi)有。

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 接口,可以簡(jiǎn)單理解為讀源和寫(xiě)源。也就是說(shuō),只要實(shí)現(xiàn)了 Reader 中的 Read 方法,這個(gè)東西就可以作為讀源,里面可以包含數(shù)據(jù),被我們讀取。 Writer 也是如此。

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

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

相關(guān)文章

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

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

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

    Go語(yǔ)言清除文件中空行的方法

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

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

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

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

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

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

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

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

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

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

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

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

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

    Go語(yǔ)言sync包與鎖實(shí)現(xiàn)限制線程對(duì)變量的訪問(wèn)

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

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

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

最新評(píng)論