Go語(yǔ)言文件開關(guān)及讀寫操作示例
?? 實(shí)戰(zhàn)場(chǎng)景
本篇博客為大家再次帶來(lái) Go 語(yǔ)言的基礎(chǔ)知識(shí),這次要學(xué)習(xí)的內(nèi)容是 Go 中的文件操作。
打開關(guān)閉文件
在 Go 中操作文件,首先要做的就是導(dǎo)入 os 模塊,該模塊中具備相關(guān)函數(shù)定義。
package main
import (
"fmt"
"os"
)
func main() {
// 打開文件
file, err := os.Open("./ca.txt")
if err != nil {
fmt.Println("文件打開失敗", err)
return
}
print(file) // 輸出地址 0xc000006028
// 關(guān)閉文件
file.Close()
}
如果文件打開失敗,直接展示錯(cuò)誤信息,正確的話,會(huì)返回 file 對(duì)象的地址。
讀取文件
使用 Read 函數(shù)讀取文件,其定義如下所示:
func (f *File) Read(b [] byte)(n int,err error)
從定義中可以發(fā)現(xiàn),Read 函數(shù)會(huì)返回 2 個(gè)值,第一個(gè)是讀取的字節(jié)數(shù),第二個(gè)是當(dāng)讀取報(bào)錯(cuò)時(shí),返回錯(cuò)誤信息,示例代碼如下所示:
package main
import (
"fmt"
"io"
"os"
)
func main() {
// 打開文件
file, err := os.Open("./ca.txt")
if err != nil {
fmt.Println("打開文件失敗,錯(cuò)誤信息:", err)
return
}
// 為了防止忘記關(guān)閉文件,可使用defer注冊(cè)文件關(guān)閉語(yǔ)句
defer file.Close()
// Read方法讀取數(shù)據(jù)
var tmp = make([]byte, 128)
// 讀取文件
n, err := file.Read(tmp)
// 碰到 io.EOF 表示文件讀取到末尾
if err == io.EOF {
fmt.Println("文件讀取完畢")
return
}
if err != nil {
fmt.Println("讀取文件失敗,錯(cuò)誤信息:", err)
return
}
fmt.Printf("讀取了 %d 字節(jié)數(shù)據(jù)\n", n)
fmt.Println(string(tmp[:n]))
}
輸出如下內(nèi)容:
讀取了 24 字節(jié)數(shù)據(jù)
姓名:夢(mèng)想橡皮擦
讀取到 24 個(gè)字節(jié),標(biāo)準(zhǔn)的中文占 3 個(gè)字節(jié)。
但是上述代碼最大的問題就是,我們給變量 tmp,即數(shù)組 tmp 僅設(shè)置了 128 字節(jié),如果待讀取的文件超過了改值,例如 txt 內(nèi)容如下所示:
姓名:夢(mèng)想橡皮擦1
姓名:夢(mèng)想橡皮擦2
姓名:夢(mèng)想橡皮擦3
姓名:夢(mèng)想橡皮擦4
姓名:夢(mèng)想橡皮擦5
此時(shí)運(yùn)行代碼,就會(huì)發(fā)現(xiàn) Read 函數(shù)讀取到第 128 個(gè)字節(jié)的時(shí)候,就會(huì)停止讀取,間接導(dǎo)致讀取到的數(shù)據(jù)亂碼。
讀取了 128 字節(jié)數(shù)據(jù)
姓名:夢(mèng)想橡皮擦1
姓名:夢(mèng)想橡皮擦2
姓名:夢(mèng)想橡皮擦3
姓名:夢(mèng)想橡皮擦4
姓名:夢(mèng)想橡??
解決該問題,需要用到 for 循環(huán)讀取文件數(shù)據(jù),代碼如下:
package main
import (
"fmt"
"io"
"os"
)
func main() {
// 打開文件
file, err := os.Open("./ca.txt")
if err != nil {
fmt.Println("打開文件失敗,錯(cuò)誤信息:", err)
return
}
defer file.Close()
// 聲明一個(gè) content 切片
var content []byte
var tmp = make([]byte, 128)
for {
n, err := file.Read(tmp)
if err == io.EOF {
fmt.Println("文件讀取完畢")
break
}
if err != nil {
fmt.Println("讀取文件失敗,錯(cuò)誤信息:", err)
return
}
// 追加數(shù)據(jù)
content = append(content, tmp[:n]...)
}
fmt.Println(string(content))
}
上述代碼聲明了一個(gè)動(dòng)態(tài)數(shù)組,即切片,解決了讀取數(shù)據(jù)不足的問題。
bufio 讀取文件
該函數(shù)可以一次讀取一行數(shù)據(jù),示例代碼如下:
func main() {
file, err := os.Open("./ca.txt")
if err != nil {
fmt.Println("打開文件失敗,錯(cuò)誤信息:", err)
return
}
defer file.Close()
reader := bufio.NewReader(file)
for {
// 逐行讀取數(shù)據(jù)
line, err := reader.ReadString('\n')
if err == io.EOF {
if len(line) != 0 {
fmt.Println(line)
}
fmt.Println("文件讀取完畢")
break
}
if err != nil {
fmt.Println("讀取文件失敗,錯(cuò)誤信息:", err)
return
}
fmt.Print(line)
}
}
該函數(shù)與 Python 中的 readline 具備同樣的效果,接下來(lái)演示一下讀取整個(gè)文件,代碼如下:
package main
import (
"fmt"
"io/ioutil"
)
func main() {
content, err := ioutil.ReadFile("./ca.txt")
if err != nil {
fmt.Println("打開文件失敗,錯(cuò)誤信息:", err)
return
}
fmt.Println(string(content))
}
注意導(dǎo)入模塊的時(shí)候,直接導(dǎo)入了 io 包中的 ioutil 函數(shù)。
寫文件
使用 os.OpenFile() 函數(shù)可以指定模式打開文件,即可以寫入的方式打開文件。
寫入文件最常用的函數(shù)是 Write和 WriteString,示例代碼如下所示:
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.OpenFile("ca.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
if err != nil {
fmt.Println("打開文件失敗,錯(cuò)誤信息:", err)
return
}
defer file.Close()
name := "橡皮擦"
file.Write([]byte(name)) //寫入字節(jié)切片
file.WriteString("夢(mèng)想橡皮擦") //寫入字符串
}
使用該方式寫入文件,會(huì)覆蓋之前的文件內(nèi)容,查看結(jié)果可直接打開目錄下的 ca.txt 進(jìn)行查看。
我們將 os.OpenFile("ca.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) 中的參數(shù)進(jìn)行單獨(dú)的說(shuō)明。
第一個(gè)參數(shù)表示文件名,第二個(gè)參數(shù)是打開文件的模式,具體模式如下所示:
os.O_WRONLY:只寫;
os.O_CREATE:創(chuàng)建文件;
os.O_RDONLY:只讀;
os.O_RDWR:讀寫;
os.O_TRUNC:清空;
os.O_APPEND:追加。
可以看到與 Python 中的文件模式基本一致。
最后一個(gè)參數(shù)值 0666 表示文件權(quán)限(八進(jìn)制),這與 linux 文件權(quán)限數(shù)字一致,讀 r 等于 4(感謝博友指出該錯(cuò)誤),寫 w 表示 2,執(zhí)行 x 等于 1,所以 666 表示的是文件可讀,可寫。
在文件寫入部分,還存在 bufio.NewWriter 整行寫入,ioutil.WriteFile 整體寫入等內(nèi)容,可以學(xué)習(xí)的時(shí)候重點(diǎn)查閱一下。
以上就是Go語(yǔ)言文件開關(guān)及讀寫操作示例的詳細(xì)內(nèi)容,更多關(guān)于Go文件開關(guān)讀寫操作的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
手把手帶你走進(jìn)Go語(yǔ)言之語(yǔ)法基礎(chǔ)解析
這篇文章主要介紹了手把手帶你走進(jìn)Go語(yǔ)言之語(yǔ)法基礎(chǔ),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
Go語(yǔ)言開發(fā)代碼自測(cè)絕佳go?fuzzing用法詳解
這篇文章主要為大家介紹了Go語(yǔ)言開發(fā)代碼自測(cè)絕佳go?fuzzing用法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Go語(yǔ)言中GORM存取數(shù)組/自定義類型數(shù)據(jù)
在使用gorm時(shí)往往默認(rèn)的數(shù)據(jù)類型不滿足我們的要求,需要使用一些自定義數(shù)據(jù)類型作為字段類型,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言中GORM存取數(shù)組/自定義類型數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2023-01-01
Go語(yǔ)言strconv包實(shí)現(xiàn)字符串和數(shù)值類型的相互轉(zhuǎn)換
這篇文章主要介紹了Go語(yǔ)言strconv包實(shí)現(xiàn)字符串和數(shù)值類型的相互轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
golang語(yǔ)言實(shí)現(xiàn)的文件上傳與文件下載功能示例
這篇文章主要介紹了golang語(yǔ)言實(shí)現(xiàn)的文件上傳與文件下載功能,結(jié)合實(shí)例形式分析了Go語(yǔ)言實(shí)現(xiàn)的文件傳輸相關(guān)操作技巧,需要的朋友可以參考下2020-02-02
淺析Golang如何向已關(guān)閉的chan讀寫數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了Golang如何向已關(guān)閉的chan讀寫數(shù)據(jù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02
Golang算法問題之整數(shù)拆分實(shí)現(xiàn)方法分析
這篇文章主要介紹了Golang算法問題之整數(shù)拆分實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Go語(yǔ)言數(shù)值運(yùn)算與數(shù)組遍歷相關(guān)操作技巧,需要的朋友可以參考下2017-02-02
Golang HTTP 服務(wù)平滑重啟及升級(jí)的思路
Golang HTTP服務(wù)在上線時(shí),需要重新編譯可執(zhí)行文件,關(guān)閉正在運(yùn)行的進(jìn)程,然后再啟動(dòng)新的運(yùn)行進(jìn)程。這篇文章主要介紹了Golang HTTP 服務(wù)平滑重啟及升級(jí),需要的朋友可以參考下2020-04-04
使用go net實(shí)現(xiàn)簡(jiǎn)單的redis通信協(xié)議
本文主要介紹了go net實(shí)現(xiàn)簡(jiǎn)單的redis通信協(xié)議,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12

