一篇文章帶你搞定Go語言基礎(chǔ)之文件操作
前言
Hey,大家好呀,我是Go進(jìn)階者,這次咱們來說一下文件操作。
文件操作就簡單了,像打開word了,excel了,都是文件操作,當(dāng)然,我們肯定是不能直接操作word的
我們就從最簡單的普通文件開始叭!
打開和關(guān)閉文件
- package main
- import "os"
- func main() {
- //os.Open是只讀模式
- fileObj, err := os.Open("永不退縮.txt")
- if err != nil {
- panic(err)
- }
- //關(guān)閉文件
- fileObj.Close()
- //一般情況下使用這種方式關(guān)閉文件
- defer fileObj.Close()
- }
注:如果你使用的是Goland,在學(xué)習(xí)文件操作這一塊時(shí),盡量不要右擊運(yùn)行,因?yàn)椴檎椅募窂讲灰粯?/p>
盡可能的編譯成.exe文件,這樣找的就是當(dāng)前目錄
讀取文件
讀取指定大小
代碼
- func main() {
- //os.Open是只讀模式
- fileObj, err := os.Open("永不退縮.txt")
- if err != nil {
- panic(err)
- }
- var fileBytes = make([]byte,128)
- n, err := fileObj.Read(fileBytes)
- if err != nil {
- panic(err)
- }
- fmt.Println(string(fileBytes[:n]))
- //一般情況下使用這種方式關(guān)閉文件
- defer fileObj.Close()
- }
執(zhí)行結(jié)果
可以發(fā)現(xiàn),根本就沒有讀取完,并且還亂碼了。
讀取整個(gè)文件
上述我們只讀取了128個(gè)字節(jié),一個(gè)中文3個(gè)字節(jié),128/3,除下標(biāo)點(diǎn)符號,應(yīng)該是40個(gè)左右,明顯不夠
那該怎么辦才能讀取所有呢???
上述我們只讀取了128個(gè)字節(jié),我們可以在讀取128個(gè)字節(jié)啊
然后找個(gè)罐子將每次讀取的都裝進(jìn)去,讀取完,裝完,完美
代碼
- func main() {
- //os.Open是只讀模式
- fileObj, err := os.Open("永不退縮.txt")
- if err != nil {
- panic(err)
- }
- //一般情況下使用這種方式關(guān)閉文件
- defer fileObj.Close()
- var 罐子 []string
- var 每次讀取字節(jié) = make([]byte,128)
- for{
- n, err := fileObj.Read(每次讀取字節(jié))
- //err == io.EOF表示讀完了,一定要放在err != nil前面
- if err == io.EOF {
- break
- }
- if err != nil {
- panic(err)
- }
- var 每次讀取字符串 = string(每次讀取字節(jié)[:n])
- 罐子 = append(罐子,每次讀取字符串)
- }
- fmt.Println(罐子)
- }
執(zhí)行結(jié)果
會發(fā)現(xiàn)還是有亂碼,這是為啥???
這是因?yàn)槲覀兠看味际前凑兆止?jié)來讀取一部分,一部分的,但是中文是3個(gè)字節(jié),所有有時(shí)候可能切錯(cuò)了,就出現(xiàn)了亂碼
那咋辦呢?沒辦法,默認(rèn)的讀取文件就這么點(diǎn)功能,更多功能,盡在bufio
bufio
bufio
可以理解為原生file操作的一個(gè)加強(qiáng)版,更牛叉,功能更多
還是上述這個(gè)文件,看看如何完美讀取
代碼
- func main() {
- //os.Open是只讀模式
- fileObj, err := os.Open("永不退縮.txt")
- if err != nil {
- panic(err)
- }
- //一般情況下使用這種方式關(guān)閉文件
- defer fileObj.Close()
- //需要將文件對象傳進(jìn)去
- reader := bufio.NewReader(fileObj)
- for{
- //按行讀取
- row, err := reader.ReadString('\n')//參數(shù)是字符,不是字符串
- if err == io.EOF {
- break
- }
- if err != nil {
- panic(err)
- }
- fmt.Printf("%v",row)
- }
- }
執(zhí)行結(jié)果
讀取整個(gè)文件
可能又有人說了,啊,星期八,我感覺還是麻煩,有沒有更簡單的辦法讀取文件,肯定有呀,一次性讀取所有呢?答案是肯定的,此時(shí)需要用到ioutil包。
代碼
- func main() {
- //os.Open是只讀模式
- bytes, err := ioutil.ReadFile("永不退縮.txt")
- if err != nil {
- panic(err)
- }
- fmt.Println(string(bytes))
- }
執(zhí)行結(jié)果
但是這種有個(gè)缺點(diǎn),只能讀取小文件,要是來個(gè)10G文件也這樣玩,保證電腦死翹翹!!!
寫入文件
寫入文件的話,我們就需要使用openFile這個(gè)方法打開文件
在開始之前呢,先記一下下面幾種模式
- os.O_WRONLY 只寫
- os.O_RDONLY 只讀
- os.O_CREATE 如果文件不存在,則創(chuàng)建文件
- os.O_RDWR 可讀可寫
- os.O_TRUNC 清空
- os.O_APPEND 追加文件
寫入字節(jié)和寫入行
代碼
- func main() {
- fileObj, err := os.OpenFile("臨時(shí).txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
- if err != nil {
- panic(err)
- }
- defer fileObj.Close()
- w_content := "我是臨時(shí)表內(nèi)容\n"
- //Write方法需要將字符串轉(zhuǎn)成字節(jié)
- fileObj.Write([]byte(w_content))
- //WriteString直接寫入字符串
- fileObj.WriteString(w_content)
- }
執(zhí)行結(jié)果
bufio寫文件
代碼
- func main() {
- fileObj, err := os.OpenFile("臨時(shí).txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
- if err != nil {
- panic(err)
- }
- defer fileObj.Close()
- w_content := "我是臨時(shí)表內(nèi)容\n"
- writer := bufio.NewWriter(fileObj)
- writer.Write([]byte(w_content))
- writer.WriteString(w_content)
- //寫完必須刷入
- writer.Flush()
- }
執(zhí)行結(jié)果
ioutil寫文件
代碼
- func main() {
- w_content := "我是臨時(shí)表內(nèi)容\n"
- err := ioutil.WriteFile("臨時(shí).txt", []byte(w_content), 0666)
- if err != nil {
- panic(err)
- }
- }
執(zhí)行結(jié)果
拷貝文件
拷貝文件,就是拷貝文件唄,A文件拷貝到B文件中
其實(shí)他的底層還是打開倆文件,把A文件內(nèi)容寫入到B文件中
代碼
- func main() {
- 原文件, err := os.Open("永不退縮.txt")
- if err != nil {
- panic(err)
- }
- defer 原文件.Close()
- 目標(biāo)文件, err := os.OpenFile("臨時(shí).txt", os.O_WRONLY|os.O_CREATE, 0666)
- if err != nil {
- panic(err)
- }
- defer 目標(biāo)文件.Close()
- //拷貝文件
- io.Copy(目標(biāo)文件,原文件)
- }
執(zhí)行結(jié)果
總結(jié)
本次章節(jié)我們主要學(xué)習(xí)文件操作的相關(guān)知識,主要分為讀取文件和寫入文件
讀取文件都有原生方法讀寫和bufio加強(qiáng)讀寫和ioutil一次性讀寫
推薦大家使用bufio這個(gè)包操作文件,帶有緩沖功能,性能更好!!
本文轉(zhuǎn)載自微信公眾號「Go語言進(jìn)階學(xué)習(xí)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Go語言進(jìn)階學(xué)習(xí)公眾號。