一文帶你掌握Go語(yǔ)言中的文件讀取操作
os 包 和 bufio 包
Go 標(biāo)準(zhǔn)庫(kù)的 os
包,為我們提供很多操作文件的函數(shù),如 Open(name)
打開(kāi)文件、Create(name)
創(chuàng)建文件等函數(shù),與之對(duì)應(yīng)的是 bufio
包,os
包是直接對(duì)磁盤(pán)進(jìn)行操作的,而 bufio
包則是帶有緩沖的操作,不用每次都去操作磁盤(pán)。
os.Open 與 os.OpenFile 以及 File.Read
Open(name string) (*File, error)
通過(guò) 文件名 或 文件路徑+文件名 的形式打開(kāi)一個(gè)文件,此文件只能用于讀操作,如果文件不存在則返回 PathError
。
- 參數(shù)
name
為文件名或文件路徑+文件名。 - 返回值
*File
為一個(gè)File
結(jié)構(gòu)體的指針類(lèi)型,通過(guò)指針可以對(duì)文件進(jìn)行讀寫(xiě)等操作。 - 返回值
error
為打開(kāi)文件的過(guò)程中產(chǎn)生的錯(cuò)誤。
OpenFile(name string, flag int, perm FileMode) (*File, error)
通過(guò)指定 文件名 或 文件路徑+文件名、文件操作模式、文件權(quán)限三個(gè)參數(shù)打開(kāi)一個(gè)文件,之后可對(duì)此文件進(jìn)行讀寫(xiě)操作。
- 參數(shù)
name
為文件名或文件路徑+文件名。 - 參數(shù)
flag
為指定文件操作模式,可選值有O_RDONLY
→ 只讀操作、O_WRONLY
→ 只寫(xiě)操作、O_RDWR
→ 讀寫(xiě)操作、O_APPEND
→ 寫(xiě)入時(shí)向文件追加數(shù)據(jù)、O_CREATE
→ 如果不存在,則創(chuàng)建一個(gè)新文件等。 - 參數(shù)
perm
參數(shù)表示文件的模式和權(quán)限,例如0666
為讀寫(xiě)權(quán)限。如果對(duì)文件權(quán)限所對(duì)應(yīng)的數(shù)字不了解,可以去學(xué)習(xí)一下。 - 返回值
*File
為一個(gè)File
結(jié)構(gòu)體的指針類(lèi)型,通過(guò)指針可以對(duì)文件進(jìn)行讀寫(xiě)等操作。 - 返回值
error
為打開(kāi)文件的過(guò)程中產(chǎn)生的錯(cuò)誤。
File.Read(b []byte) (n int, err error)
讀取與 b
等長(zhǎng)度的字節(jié),并存儲(chǔ)到 b
里面。
- 參數(shù)
b
為一個(gè)切片數(shù)組,用于指定讀取長(zhǎng)度和存儲(chǔ)字節(jié)數(shù)據(jù)。 - 返回值
n
為所讀取字節(jié)的長(zhǎng)度。 - 返回值
error
為讀取字節(jié)的過(guò)程中產(chǎn)生的錯(cuò)誤。
讀取文件操作
import ( "fmt" "os" ) func main() { file, err := os.Open("1.txt") if err != nil { fmt.Println(err) return } defer file.Close() data := make([]byte, 11) count, err := file.Read(data) if err != nil { return } fmt.Println("字節(jié)數(shù)據(jù):", data) // [72 101 108 108 111 32 119 111 114 108 100] fmt.Println("字符串?dāng)?shù)據(jù):", string(data)) // Hello world fmt.Println("所獲取字節(jié)的長(zhǎng)度:", count) // 11 }
執(zhí)行結(jié)果:
字節(jié)數(shù)據(jù): [72 101 108 108 111 32 119 111 114 108 100]
字符串?dāng)?shù)據(jù): Hello world
所獲取字節(jié)的長(zhǎng)度: 11
- 首先通過(guò)
Open
函數(shù)打開(kāi)1.txt
文件,用file
變量接收,默認(rèn)為可讀模式; - 然后創(chuàng)建一個(gè)長(zhǎng)度為
11
的字節(jié)切片,接著通過(guò)file
變量的方法Read
讀取長(zhǎng)度為11
的字節(jié)數(shù)據(jù)。os.Open("1.txt")
等價(jià)于os.OpenFile("1.txt", os.O_RDONLY, 0)
。 - 最后打印讀取到的數(shù)據(jù)。
bufio.NewReader 和 Reader.ReadString
讀取文件,建議使用 bufio.NewReader
和 Reader.ReadString
,減少磁盤(pán)的操作。
NewReader(rd io.Reader) *Reader
獲取一個(gè)有緩沖區(qū)的 Reader
指針變量,緩沖區(qū)默認(rèn)大小為 4096
字節(jié)。通過(guò)變量可以對(duì)數(shù)據(jù)進(jìn)行讀操作。
- 參數(shù)
rd
為一個(gè)接口,實(shí)現(xiàn)這個(gè)接口的數(shù)據(jù)類(lèi)型變量都可以作為參數(shù),例如上面提到的File
。 - 返回值
*Reader
為Reader
結(jié)構(gòu)體的指針,通過(guò)指針可以讀取緩沖區(qū)的數(shù)據(jù)。
ReadString(delim byte) (string, error)
讀取數(shù)據(jù),直到第一次遇到分隔符 delim
為止。讀取過(guò)程中發(fā)生錯(cuò)誤會(huì)返回 EOF
錯(cuò)誤信息。
- 參數(shù)
delim
為分隔符,每次讀取時(shí)遇到分隔符就會(huì)終止。 - 第一個(gè)返回值為所讀取的內(nèi)容,內(nèi)容包括分隔符。
- 第二個(gè)返回值為讀取過(guò)程中產(chǎn)生的錯(cuò)誤信息。
讀取文件操作
1.txt 文件的內(nèi)容為:
Hello world Hello Golang Hello Gopher
import ( "bufio" "fmt" "io" "os" "strings" ) func main() { file, err := os.OpenFile("1.txt", os.O_RDONLY, 0) if err != nil { fmt.Println(err) return } defer file.Close() reader := bufio.NewReader(file) for { if lineData, err := reader.ReadString('\n'); err != nil { if err == io.EOF { // 因?yàn)槭且該Q行符為分隔符,如果最后一行沒(méi)有換行符,那么返回 io.EOF 錯(cuò)誤時(shí),也是可能讀到數(shù)據(jù)的,因此判斷一下是否讀到了數(shù)據(jù) if len(lineData) > 0 { fmt.Println(lineData) } break } } else { fmt.Println(strings.TrimRight(lineData, "\n")) } } }
執(zhí)行結(jié)果:
Hello World
Hello Golang
Hello Gopher
- 首先通過(guò)
OpenFile
函數(shù)打開(kāi)1.txt
文件,用file
變量接收,指定為可讀模式; - 然后通過(guò)
NewReader
函數(shù)創(chuàng)建一個(gè)緩沖區(qū),將默認(rèn)長(zhǎng)度的字節(jié)讀取到緩沖區(qū)中; - 接著通過(guò)
Reader
結(jié)構(gòu)體的方法ReadString
,以\n
為分隔符,按行讀取數(shù)據(jù),然后打印數(shù)據(jù)。 - 其中有一個(gè)注意點(diǎn)就是,因?yàn)槭且該Q行符為分隔符,如果最后一行沒(méi)有換行符,那么返回
io.EOF
錯(cuò)誤時(shí),也是可能讀到數(shù)據(jù)的,因此需要判斷一下是否讀到了數(shù)據(jù)。
小結(jié)
本文先是對(duì) os
包 和 bufio
包進(jìn)行簡(jiǎn)單的介紹,然后介紹 os
包里的 Open
和 OpenFile
函數(shù)以及 File
結(jié)構(gòu)體的方法 Read
,通過(guò)案例展示它們的使用方式。緊接著引出 bufio
包里的 NewReader
函數(shù)和 Reader
結(jié)構(gòu)體的方法 ReadString
,讀取文件的操作推薦使用它們,能減少對(duì)磁盤(pán)的操作,高效讀取數(shù)據(jù)。
到此這篇關(guān)于一文帶你掌握Go語(yǔ)言中的文件讀取操作的文章就介紹到這了,更多相關(guān)Go語(yǔ)言文件讀取內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Go語(yǔ)言編寫(xiě)簡(jiǎn)潔代碼的最佳實(shí)踐
簡(jiǎn)潔的代碼對(duì)于創(chuàng)建可維護(hù)、可閱讀和高效的軟件至關(guān)重要,Go 是一種強(qiáng)調(diào)簡(jiǎn)單和代碼整潔的語(yǔ)言,在本文中,我們將結(jié)合代碼示例,探討編寫(xiě)簡(jiǎn)潔 Go 代碼的最佳實(shí)踐,需要的朋友可以參考下2023-09-09解決goxorm無(wú)法更新值為默認(rèn)值的問(wèn)題
這篇文章主要介紹了解決goxorm無(wú)法更新值為默認(rèn)值的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12GoFrame框架gcache的緩存控制淘汰策略實(shí)踐示例
這篇文章主要為大家介紹了GoFrame框架gcache的緩存控制淘汰策略的實(shí)踐示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06Golang 語(yǔ)言map底層實(shí)現(xiàn)原理解析
這篇文章主要介紹了Golang 語(yǔ)言map底層實(shí)現(xiàn)原理解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12Golang實(shí)現(xiàn)驗(yàn)證一個(gè)字符串是否為URL
在實(shí)際開(kāi)發(fā)過(guò)程中,有時(shí)候會(huì)遇到?URL?的校驗(yàn)問(wèn)題,Go?語(yǔ)言中有哪些方法去驗(yàn)證一個(gè)字符串是否滿足?URL?格式呢?本文就來(lái)和大家詳細(xì)講講2023-04-04使用Golang快速構(gòu)建出命令行應(yīng)用程序
在日常開(kāi)發(fā)中,大家對(duì)命令行工具(CLI)想必特別熟悉了,如果說(shuō)你不知道命令工具,那你可能是個(gè)假開(kāi)發(fā)。每天都會(huì)使用大量的命令行工具,例如最常用的Git、Go、Docker等,這篇文章主要介紹了使用Golang快速構(gòu)建出命令行應(yīng)用程序,需要的朋友可以參考下2023-02-02