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

Go語言中緩沖bufio的原理解讀與應(yīng)用實戰(zhàn)

 更新時間:2024年10月22日 09:38:50   作者:景天科技苑  
Go語言標準庫中的bufio包提供了帶緩沖的I/O操作,它通過封裝io.Reader和io.Writer接口,減少頻繁的I/O操作,提高讀寫效率,本文就來詳細的介紹一下,感興趣的可以學(xué)習(xí)

bufio是Go語言標準庫中的一個重要包,它提供了帶緩沖的I/O操作,用于包裝io.Reader或io.Writer對象,以減少I/O操作的次數(shù),從而提高讀寫性能。本文將結(jié)合實際案例,詳細講解bufio在Go語言中的用法。

Go語言自帶的IO操作包。bufio,使用這個包可以大幅提升文件的讀寫效率。

  • buf: 緩沖區(qū).
  • io操作效率本身是還可以的,頻繁訪問本地磁盤文件(效率低)

所以說 bufio ,提供了一個緩沖區(qū),讀和寫都先在緩沖區(qū)中,最后再一次性讀取或者寫入到文件里,降低訪問本地磁盤的次數(shù)。

在這里插入圖片描述

一、bufio的基本概念和原理

bufio的主要作用是減少I/O操作的次數(shù),提供讀寫性能。其工作原理是通過在內(nèi)存中維護一個緩沖區(qū),先將數(shù)據(jù)讀入緩沖區(qū),再從緩沖區(qū)中讀取數(shù)據(jù),從而減少對底層I/O設(shè)備的訪問次數(shù)。

bufio的主要對象是緩沖區(qū),操作主要有兩個:讀和寫。讀操作時,如果緩沖區(qū)為空,則從文件讀取數(shù)據(jù)填滿緩沖區(qū);如果緩沖區(qū)不為空,則從緩沖區(qū)讀取數(shù)據(jù)。寫操作時,如果緩沖區(qū)未滿,則將數(shù)據(jù)寫入緩沖區(qū);如果緩沖區(qū)已滿,則將緩沖區(qū)的數(shù)據(jù)寫入文件,并繼續(xù)寫入剩余的數(shù)據(jù)。

二、bufio的讀操作

bufio的讀操作主要通過bufio.Reader對象實現(xiàn),它提供了多種讀取數(shù)據(jù)的方法,如Read、ReadLine、ReadString等。

1. 使用bufio.Reader讀取文件內(nèi)容

下面是一個使用bufio.Reader讀取文件內(nèi)容的示例:

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

func main() {
	// 打開文件
	file, err := os.Open("example.txt")
	if err != nil {
		fmt.Println("read file err:", err)
		return
	}
	defer file.Close() // 使用defer關(guān)閉文件

	// 創(chuàng)建bufio.Reader對象。借助bufio來讀取文件內(nèi)容
	// func NewReader(rd io.Reader) *Reader
	reader := bufio.NewReader(file)

	// 循環(huán)讀取文件內(nèi)容
	for {

		// 通過Read方法Read()讀取文件
		//buf := make([]byte, 1024)
		//n, err := bufioReader.Read(buf)
		//fmt.Println("讀取到了多少個字節(jié):", n)
		//讀取到的內(nèi)容
		//fmt.Println("讀取到的內(nèi)容:",string(buf[:n]))

		//通過ReadString方法讀取文件
		// func (b *Reader) ReadString(delim byte) (string, error)
		//參數(shù)是以什么作為分隔符。讀取得到的是字符串
		//注意,最后一行后面要是沒有換行符,讀取不到
		str, err := reader.ReadString('\n') // 讀取字符串,以換行符為分隔符
		if err == io.EOF {                  // 判斷文件是否結(jié)尾
			break
		} else if err != nil { // 判斷錯誤,打印錯誤
			fmt.Printf("read file failed, err:%v", err)
			break
		}
		//循環(huán)中逐行打印出讀取的內(nèi)容
		fmt.Printf("read string SuccessFull: %s\n", str) // 打印讀取的文件內(nèi)容
	}
}

在這里插入圖片描述

在這個示例中,我們首先使用os.Open函數(shù)打開文件,然后創(chuàng)建一個bufio.Reader對象,通過循環(huán)調(diào)用ReadString方法讀取文件內(nèi)容,每次讀取一行。當(dāng)遇到文件結(jié)尾時,ReadString方法會返回一個io.EOF錯誤,我們據(jù)此退出循環(huán)。

2. 統(tǒng)計文件中字符、空格、數(shù)字和其他字符的數(shù)量

下面是一個統(tǒng)計文件中字符、空格、數(shù)字和其他字符數(shù)量的示例:

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

// CharCount 定義結(jié)構(gòu)體
type CharCount struct {
	ChCount    int
	NumCount   int
	SpaceCount int
	OtherCount int
}

func main() {
	// 打開文件
	file, err := os.Open("example.txt")
	if err != nil {
		fmt.Println("read file err:", err)
		return
	}
	defer file.Close() // 使用defer關(guān)閉文件

	// 創(chuàng)建bufio.Reader對象
	reader := bufio.NewReader(file)

	var count CharCount

	// 循環(huán)讀取文件內(nèi)容
	for {
		//str, err := reader.ReadString('\n') // 讀取字符串,以換行符為分隔符
		str, _, err := reader.ReadLine() // 按行讀取,最后一行沒有換行符也能讀到
		if err == io.EOF {               // 判斷文件是否結(jié)尾
			break
		}
		if err != nil { // 判斷錯誤,打印錯誤
			fmt.Printf("read file failed, err:%v", err)
			break
		}

		//runeArr := []rune(str) // 將字符串轉(zhuǎn)為切片類型
		runeArr := str // 將字符串轉(zhuǎn)為切片類型
		fmt.Println("得到的數(shù)據(jù)是", string(runeArr))
		for _, v := range runeArr { // 循環(huán)讀取數(shù)組
			switch {
			case v >= 'a' && v <= 'z': // 判斷是不是小寫字母
				fallthrough
			case v >= 'A' && v <= 'Z': // 判斷是不是大寫字母
				count.ChCount++
			case v == ' ' || v == '\t': // 判斷是不是空格
				count.SpaceCount++
			case v >= '0' && v <= '9': // 判斷是不是數(shù)字
				count.NumCount++
			default:
				count.OtherCount++
			}
		}
	}

	fmt.Printf("char count:%d\n", count.ChCount)
	fmt.Printf("num count:%d\n", count.NumCount)
	fmt.Printf("space count:%d\n", count.SpaceCount)
	fmt.Printf("other count:%d\n", count.OtherCount)
}

在這里插入圖片描述

3. 使用Scanner讀取標準輸入

下面是一個使用bufio.Scanner讀取標準輸入的示例:

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	// 讀取鍵盤的輸入
	// 鍵盤的輸入,實際上是流 os.Stdin
	inputReader := bufio.NewReader(os.Stdin)
	// delim 到哪里結(jié)束讀取 以換行符作為分隔符,之言不換行就可以一直讀
	readString, _ := inputReader.ReadString('\n')
	fmt.Println("讀取鍵盤輸入的信息:", readString)
}

在這里插入圖片描述

三、bufio的寫操作

bufio的寫操作主要通過bufio.Writer對象實現(xiàn),它提供了多種寫入數(shù)據(jù)的方法,如Write、WriteString、Flush等。

1. 使用bufio.Writer寫入文件內(nèi)容

下面是一個使用bufio.Writer寫入文件內(nèi)容的示例:

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	// 打開文件句柄,以寫的方式打開,如果文件不存在則創(chuàng)建
	file, err := os.OpenFile("F:\\goworks\\src\\jingtian\\yufa\\io操作\\bufio操作\\test_go_file.log",
		os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		fmt.Println("open file error:", err)
		return
	}
	defer file.Close() // 使用的defer語句關(guān)閉文件

	// 創(chuàng)建bufio.Writer對象
	fileWrite := bufio.NewWriter(file)

	inputStr := "Hello World ...\n"
	for i := 0; i < 10; i++ { // 循環(huán)寫入數(shù)據(jù)
		fileWrite.WriteString(inputStr)
	}
	// 發(fā)現(xiàn)并沒有寫出到文件,是留在了緩沖區(qū),所以我們需要調(diào)用 flush 刷新緩沖區(qū)
	// 必須手動刷新才能寫入進文件
	fileWrite.Flush() // 刷新緩沖區(qū),將數(shù)據(jù)寫入文件
}

在這里插入圖片描述

在這個示例中,我們首先使用os.OpenFile函數(shù)打開文件,然后創(chuàng)建一個bufio.Writer對象,通過循環(huán)調(diào)用WriteString方法寫入文件內(nèi)容。最后,我們調(diào)用Flush方法刷新緩沖區(qū),將數(shù)據(jù)寫入文件。

2. 自定義io.Writer對象進行緩沖寫

下面是一個自定義io.Writer對象進行緩沖寫的示例:

package main

import (
	"bufio"
	"fmt"
	"io"
	"strings"
)

// 自定義一個io.Writer對象
type StringWriter struct{}

func (s StringWriter) Write(p []byte) (n int, err error) {
	// 這里簡單地將數(shù)據(jù)寫入一個字符串變量(實際使用時,可以將其寫入內(nèi)存、文件等)
	fmt.Print(string(p))
	return len(p), nil
}

func main() {
	// 創(chuàng)建一個StringWriter對象
	sw := StringWriter{}

	// 創(chuàng)建一個bufio.Writer對象,并傳入StringWriter對象
	writer := bufio.NewWriterSize(sw, 10)

	// 寫入數(shù)據(jù)
	writer.WriteString("Hello, ")
	writer.WriteString("world!\n")

	// 刷新緩沖區(qū),將數(shù)據(jù)寫入StringWriter對象
	writer.Flush()
}

在這個示例中,我們自定義了一個StringWriter對象,它實現(xiàn)了io.Writer接口的Write方法。然后,我們創(chuàng)建一個bufio.Writer對象,并傳入StringWriter對象。接著,我們調(diào)用WriteString方法寫入數(shù)據(jù),并調(diào)用Flush方法刷新緩沖區(qū),將數(shù)據(jù)寫入StringWriter對象。

四、bufio的緩沖區(qū)大小

在bufio包中,Reader和Writer對象都有默認的緩沖區(qū)大小,但你也可以根據(jù)需要自定義緩沖區(qū)大小。

1. 默認緩沖區(qū)大小

對于bufio.Readerbufio.Writer,Go語言標準庫為它們提供了默認的緩沖區(qū)大小。對于bufio.Reader,默認緩沖區(qū)大小通常是4096字節(jié)(4KB);對于bufio.Writer,默認緩沖區(qū)大小也是4096字節(jié)(但在某些實現(xiàn)中可能略有不同,具體取決于底層操作系統(tǒng)的I/O性能)。

2. 自定義緩沖區(qū)大小

如果你需要更大的緩沖區(qū)來提高性能,或者更小的緩沖區(qū)來減少內(nèi)存使用,你可以使用bufio.NewReaderSizebufio.NewWriterSize函數(shù)來創(chuàng)建具有自定義緩沖區(qū)大小的Reader和Writer對象。

下面是一個自定義緩沖區(qū)大小的示例:

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	// 打開文件
	file, err := os.OpenFile("F:\\goworks\\src\\jingtian\\yufa\\io操作\\bufio操作\\custom_buffer_file.log", os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		fmt.Println("open file error:", err)
		return
	}
	defer file.Close() // 使用defer語句關(guān)閉文件

	// 自定義緩沖區(qū)大?。ɡ纾?KB)
	bufferSize := 8 * 1024

	// 創(chuàng)建具有自定義緩沖區(qū)大小的bufio.Writer對象
	fileWrite := bufio.NewWriterSize(file, bufferSize)

	inputStr := "This is a line with custom buffer size.\n"
	for i := 0; i < 10; i++ { // 循環(huán)寫入數(shù)據(jù)
		_, err := fileWrite.WriteString(inputStr)
		if err != nil {
			fmt.Println("write file error:", err)
			return
		}
	}

	// 刷新緩沖區(qū),將數(shù)據(jù)寫入文件
	err = fileWrite.Flush()
	if err != nil {
		fmt.Println("flush buffer error:", err)
		return
	}

	fmt.Println("Data written to file successfully with custom buffer size.")
}

在這個示例中,我們創(chuàng)建了一個具有8KB緩沖區(qū)大小的bufio.Writer對象,并將其用于將數(shù)據(jù)寫入文件。注意,在寫入數(shù)據(jù)后,我們調(diào)用了Flush方法來確保緩沖區(qū)中的數(shù)據(jù)被寫入文件。

對于bufio.Reader,你也可以使用類似的方法來創(chuàng)建具有自定義緩沖區(qū)大小的對象:

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	// 打開文件
	file, err := os.Open("F:\\goworks\\src\\jingtian\\yufa\\io操作\\bufio操作\\custom_buffer_file.log")
	if err != nil {
		fmt.Println("read file error:", err)
		return
	}
	defer file.Close() // 使用defer語句關(guān)閉文件

	// 自定義緩沖區(qū)大小(例如:8KB)
	bufferSize := 8 * 1024

	// 創(chuàng)建具有自定義緩沖區(qū)大小的bufio.Reader對象
	fileRead := bufio.NewReaderSize(file, bufferSize)

	// 讀取文件內(nèi)容(這里只是簡單地讀取并打印每一行)
	for {
		line, err := fileRead.ReadString('\n')
		if err != nil {
			if err.Error() == "EOF" { // 判斷是否到達文件末尾
				break
			}
			fmt.Println("read file error:", err)
			return
		}
		fmt.Print(line) // 打印讀取到的行
	}

	fmt.Println("File read successfully with custom buffer size.")
}

在這個示例中,我們創(chuàng)建了一個具有8KB緩沖區(qū)大小的bufio.Reader對象,并將其用于讀取文件內(nèi)容。注意,在處理文件讀取時,我們需要檢查錯誤是否為EOF(文件末尾),以確定是否應(yīng)該退出循環(huán)。

通過自定義緩沖區(qū)大小,你可以根據(jù)具體的應(yīng)用場景和需求來優(yōu)化bufio的性能和內(nèi)存使用。

到此這篇關(guān)于Go語言中緩沖bufio的原理解讀與應(yīng)用實戰(zhàn)的文章就介紹到這了,更多相關(guān)Go語言緩沖bufio內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 為什么Go語言把類型聲明放在后面?

    為什么Go語言把類型聲明放在后面?

    今天小編就為大家分享一篇關(guān)于為什么Go語言把類型聲明放在后面?,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • golang實現(xiàn)微信小程序商城后臺系統(tǒng)(moshopserver)

    golang實現(xiàn)微信小程序商城后臺系統(tǒng)(moshopserver)

    這篇文章主要介紹了golang實現(xiàn)微信小程序商城后臺系統(tǒng)(moshopserver),本文通過截圖實例代碼的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • 重學(xué)Go語言之變量與常量的聲明與使用詳解

    重學(xué)Go語言之變量與常量的聲明與使用詳解

    變量、常量的聲明與使用是掌握一門編程語言的基礎(chǔ),在這篇文章中,小編就來帶大家學(xué)習(xí)一下Go語言是怎么樣聲明和使用變量與常量吧
    2023-03-03
  • Go語言map實現(xiàn)順序讀取

    Go語言map實現(xiàn)順序讀取

    當(dāng)我們遍歷 map 時,那就是輸出的鍵值對順序是不確定的,本文主要介紹了Go語言map實現(xiàn)順序讀取, 文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • golang 中signal包的Notify用法說明

    golang 中signal包的Notify用法說明

    這篇文章主要介紹了golang 中signal包的Notify用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Golang 實現(xiàn)interface類型轉(zhuǎn)string類型

    Golang 實現(xiàn)interface類型轉(zhuǎn)string類型

    這篇文章主要介紹了Golang 實現(xiàn)interface類型轉(zhuǎn)string類型的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Golang Type關(guān)鍵字的使用

    Golang Type關(guān)鍵字的使用

    Type關(guān)鍵字在Go語言中作用很重要,比如定義結(jié)構(gòu)體,接口,還可以自定義類型,定義類型別名等,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • Golang map實踐及實現(xiàn)原理解析

    Golang map實踐及實現(xiàn)原理解析

    這篇文章主要介紹了Golang map實踐以及實現(xiàn)原理,Go 語言中,通過哈希查找表實現(xiàn) map,用鏈表法解決哈希沖突,本文結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友參考下吧
    2022-06-06
  • Golang HTTP請求Json響應(yīng)解析方法以及解讀失敗的原因

    Golang HTTP請求Json響應(yīng)解析方法以及解讀失敗的原因

    這篇文章主要介紹了Golang HTTP請求Json響應(yīng)解析方法以及解讀失敗的原因,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • golang 通過ssh代理連接mysql的操作

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

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

最新評論