最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

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

在這里插入圖片描述

一、bufio的基本概念和原理

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

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

二、bufio的讀操作

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

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

下面是一個(gè)使用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對(duì)象。借助bufio來(lái)讀取文件內(nèi)容
	// func NewReader(rd io.Reader) *Reader
	reader := bufio.NewReader(file)

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

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

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

在這里插入圖片描述

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

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

下面是一個(gè)統(tǒng)計(jì)文件中字符、空格、數(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對(duì)象
	reader := bufio.NewReader(file)

	var count CharCount

	// 循環(huán)讀取文件內(nèi)容
	for {
		//str, err := reader.ReadString('\n') // 讀取字符串,以換行符為分隔符
		str, _, err := reader.ReadLine() // 按行讀取,最后一行沒(méi)有換行符也能讀到
		if err == io.EOF {               // 判斷文件是否結(jié)尾
			break
		}
		if err != nil { // 判斷錯(cuò)誤,打印錯(cuò)誤
			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讀取標(biāo)準(zhǔn)輸入

下面是一個(gè)使用bufio.Scanner讀取標(biāo)準(zhǔn)輸入的示例:

package main

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

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

在這里插入圖片描述

三、bufio的寫操作

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

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

下面是一個(gè)使用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語(yǔ)句關(guān)閉文件

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

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

在這里插入圖片描述

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

2. 自定義io.Writer對(duì)象進(jìn)行緩沖寫

下面是一個(gè)自定義io.Writer對(duì)象進(jìn)行緩沖寫的示例:

package main

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

// 自定義一個(gè)io.Writer對(duì)象
type StringWriter struct{}

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

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

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

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

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

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

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

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

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

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

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

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

下面是一個(gè)自定義緩沖區(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語(yǔ)句關(guān)閉文件

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

	// 創(chuàng)建具有自定義緩沖區(qū)大小的bufio.Writer對(duì)象
	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.")
}

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

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

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語(yǔ)句關(guān)閉文件

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

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

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

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

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

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

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

相關(guān)文章

  • Go語(yǔ)言使用Buffer實(shí)現(xiàn)高性能處理字節(jié)和字符

    Go語(yǔ)言使用Buffer實(shí)現(xiàn)高性能處理字節(jié)和字符

    在?Go?中,bytes.Buffer?是一個(gè)非常高效的類型,用于處理字節(jié)數(shù)據(jù)的讀寫操作,本文將詳細(xì)介紹一下如何使用Buffer實(shí)現(xiàn)高性能處理字節(jié)和字符,有需要的小伙伴可以了解下
    2025-01-01
  • Go語(yǔ)言如何并發(fā)超時(shí)處理詳解

    Go語(yǔ)言如何并發(fā)超時(shí)處理詳解

    大家都知道golang并沒(méi)有在語(yǔ)言層次上提供超時(shí)操作,但可以通過(guò)一些小技巧實(shí)現(xiàn)超時(shí)。下面來(lái)一起看看吧,有需要的朋友們可以參考借鑒。
    2016-09-09
  • golang中為什么Response.Body需要被關(guān)閉詳解

    golang中為什么Response.Body需要被關(guān)閉詳解

    這篇文章主要給大家介紹了關(guān)于golang中為什么Response.Body需要被關(guān)閉的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • golang如何獲取域名ip?dns信息

    golang如何獲取域名ip?dns信息

    這篇文章主要介紹了golang如何獲取域名ip?dns信息問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-07-07
  • Go語(yǔ)言利用正則表達(dá)式處理多行文本

    Go語(yǔ)言利用正則表達(dá)式處理多行文本

    在?Go?語(yǔ)言中處理多行文本的正則表達(dá)式時(shí),換行符常常會(huì)導(dǎo)致意外的匹配結(jié)果,本文為大家整理了一些解決方法,有需要的小伙伴可以參考一下
    2024-11-11
  • Golang語(yǔ)言如何讀取http.Request中body的內(nèi)容

    Golang語(yǔ)言如何讀取http.Request中body的內(nèi)容

    這篇文章主要介紹了Golang語(yǔ)言如何讀取http.Request中body的內(nèi)容問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • sublime text3解決Gosublime無(wú)法自動(dòng)補(bǔ)全代碼的問(wèn)題

    sublime text3解決Gosublime無(wú)法自動(dòng)補(bǔ)全代碼的問(wèn)題

    本文主要介紹了sublime text3解決Gosublime無(wú)法自動(dòng)補(bǔ)全代碼的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Go語(yǔ)言異常處理案例解析

    Go語(yǔ)言異常處理案例解析

    這篇文章主要介紹了Go語(yǔ)言異常處理案例解析,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Go語(yǔ)言基礎(chǔ)切片的創(chuàng)建及初始化示例詳解

    Go語(yǔ)言基礎(chǔ)切片的創(chuàng)建及初始化示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言基礎(chǔ)切片的創(chuàng)建及初始化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2021-11-11
  • Go語(yǔ)言使用sort包對(duì)任意類型元素的集合進(jìn)行排序的方法

    Go語(yǔ)言使用sort包對(duì)任意類型元素的集合進(jìn)行排序的方法

    這篇文章主要介紹了Go語(yǔ)言使用sort包對(duì)任意類型元素的集合進(jìn)行排序的方法,實(shí)例分析了sort排序所涉及的方法與相關(guān)的使用技巧,需要的朋友可以參考下
    2015-02-02

最新評(píng)論

阜新市| 永胜县| 华亭县| 柞水县| 名山县| 清水河县| 通河县| 密山市| 吴忠市| 揭西县| 蓬安县| 唐山市| 滨州市| 盖州市| 昭平县| 常熟市| 宁城县| 安乡县| 锦州市| 时尚| 富顺县| 旬邑县| 桂东县| 抚宁县| 凤冈县| 凤凰县| 竹溪县| 电白县| 封丘县| 涡阳县| 黄陵县| 绥芬河市| 天津市| 广东省| 会东县| 汕头市| 张家川| 阜南县| 济源市| 安平县| 开远市|