一篇文章帶你搞定 Go 語言基礎之文件操作
前言
Hey,大家好呀,我是 Go 進階者,這次咱們來說一下文件操作。
文件操作就簡單了,像打開 word 了,excel 了,都是文件操作,當然,我們肯定是不能直接操作 word 的
我們就從最簡單的普通文件開始叭!
打開和關閉文件
package main
import "os"
func main() {
//os.Open是隻讀模式
fileObj, err := os.Open("永不退縮.txt")
if err != nil {
panic(err)
}
//關閉文件
fileObj.Close()
//一般情況下使用這種方式關閉文件
defer fileObj.Close()
}
注: 如果你使用的是Goland
,在學習文件操作這一塊時,儘量不要右擊運行,因爲查找文件路徑不一樣
儘可能的編譯成.exe
文件,這樣找的就是當前目錄
讀取文件
讀取指定大小
代碼
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]))
//一般情況下使用這種方式關閉文件
defer fileObj.Close()
}
執行結果
可以發現,根本就沒有讀取完,並且還亂碼了。
讀取整個文件
上述我們只讀取了 128 個字節,一箇中文 3 個字節,128/3
,除下標點符號,應該是 40 個左右,明顯不夠
那該怎麼辦才能讀取所有呢???
上述我們只讀取了 128 個字節,我們可以在讀取 128 個字節啊
然後找個罐子將每次讀取的都裝進去,讀取完,裝完,完美
代碼
func main() {
//os.Open是隻讀模式
fileObj, err := os.Open("永不退縮.txt")
if err != nil {
panic(err)
}
//一般情況下使用這種方式關閉文件
defer fileObj.Close()
var 罐子 []string
var 每次讀取字節 = make([]byte,128)
for{
n, err := fileObj.Read(每次讀取字節)
//err == io.EOF表示讀完了,一定要放在err != nil前面
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
var 每次讀取字符串 = string(每次讀取字節[:n])
罐子 = append(罐子,每次讀取字符串)
}
fmt.Println(罐子)
}
執行結果
會發現還是有亂碼,這是爲啥???
這是因爲我們每次都是按照字節來讀取一部分,一部分的,但是中文是 3 個字節,所有有時候可能切錯了,就出現了亂碼
那咋辦呢?沒辦法,默認的讀取文件就這麼點功能,更多功能,盡在bufio
bufio
bufio
可以理解爲原生 file 操作的一個加強版,更牛叉,功能更多
還是上述這個文件,看看如何完美讀取
代碼
func main() {
//os.Open是隻讀模式
fileObj, err := os.Open("永不退縮.txt")
if err != nil {
panic(err)
}
//一般情況下使用這種方式關閉文件
defer fileObj.Close()
//需要將文件對象傳進去
reader := bufio.NewReader(fileObj)
for{
//按行讀取
row, err := reader.ReadString('\n')//參數是字符,不是字符串
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
fmt.Printf("%v",row)
}
}
執行結果
讀取整個文件
可能又有人說了,啊,星期八,我感覺還是麻煩,有沒有更簡單的辦法讀取文件,肯定有呀,一次性讀取所有呢?答案是肯定的,此時需要用到ioutil
包。
代碼
func main() {
//os.Open是隻讀模式
bytes, err := ioutil.ReadFile("永不退縮.txt")
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
執行結果
但是這種有個缺點,只能讀取小文件,要是來個 10G 文件也這樣玩,保證電腦死翹翹!!!
寫入文件
寫入文件的話,我們就需要使用openFile
這個方法打開文件
在開始之前呢,先記一下下面幾種模式
-
os.O_WRONLY
只寫 -
os.O_RDONLY
只讀 -
os.O_CREATE
如果文件不存在,則創建文件 -
os.O_RDWR
可讀可寫 -
os.O_TRUNC
清空 -
os.O_APPEND
追加文件
寫入字節和寫入行
代碼
func main() {
fileObj, err := os.OpenFile("臨時.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
if err != nil {
panic(err)
}
defer fileObj.Close()
w_content := "我是臨時表內容\n"
//Write方法需要將字符串轉成字節
fileObj.Write([]byte(w_content))
//WriteString直接寫入字符串
fileObj.WriteString(w_content)
}
執行結果
bufio 寫文件
代碼
func main() {
fileObj, err := os.OpenFile("臨時.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
if err != nil {
panic(err)
}
defer fileObj.Close()
w_content := "我是臨時表內容\n"
writer := bufio.NewWriter(fileObj)
writer.Write([]byte(w_content))
writer.WriteString(w_content)
//寫完必須刷入
writer.Flush()
}
執行結果
ioutil 寫文件
代碼
func main() {
w_content := "我是臨時表內容\n"
err := ioutil.WriteFile("臨時.txt", []byte(w_content), 0666)
if err != nil {
panic(err)
}
}
執行結果
拷貝文件
拷貝文件,就是拷貝文件唄,A 文件拷貝到 B 文件中
其實他的底層還是打開倆文件,把 A 文件內容寫入到 B 文件中
代碼
func main() {
原文件, err := os.Open("永不退縮.txt")
if err != nil {
panic(err)
}
defer 原文件.Close()
目標文件, err := os.OpenFile("臨時.txt", os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
panic(err)
}
defer 目標文件.Close()
//拷貝文件
io.Copy(目標文件,原文件)
}
執行結果
總結
本次章節我們主要學習文件操作的相關知識,主要分爲讀取文件和寫入文件
讀取文件都有原生方法讀寫和 bufio 加強讀寫和 ioutil 一次性讀寫
推薦大家使用 bufio 這個包操作文件,帶有緩衝功能,性能更好!!
如果在操作過程中有任何問題,記得下面留言,我們看到會第一時間解決問題。
能堅持別人不能堅持的,才能擁有別人不能擁有的。加油
我是碼農星期八,如果覺得還不錯,記得動手點贊一下哈。
感謝你的觀看。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/CrAd58nDQ8eBMH_Kxjz9Pg