首頁 > 軟體

Go語言檔案開關及讀寫操作範例

2022-08-01 18:03:54

⛳️ 實戰場景

本篇部落格為大家再次帶來 Go 語言的基礎知識,這次要學習的內容是 Go 中的檔案操作。

開啟關閉檔案

在 Go 中操作檔案,首先要做的就是匯入 os 模組,該模組中具備相關函數定義。

package main
import (
	"fmt"
	"os"
)
func main() {
	// 開啟檔案
	file, err := os.Open("./ca.txt")
	if err != nil {
		fmt.Println("檔案開啟失敗", err)
		return
	}
	print(file) // 輸出地址 0xc000006028
	// 關閉檔案
	file.Close()
}

如果檔案開啟失敗,直接展示錯誤資訊,正確的話,會返回 file 物件的地址。

讀取檔案

使用 Read 函數讀取檔案,其定義如下所示:

func (f *File) Read(b [] byte)(n int,err error)

從定義中可以發現,Read 函數會返回 2 個值,第一個是讀取的位元組數,第二個是當讀取報錯時,返回錯誤資訊,範例程式碼如下所示:

package main
import (
	"fmt"
	"io"
	"os"
)
func main() {
	// 開啟檔案
	file, err := os.Open("./ca.txt")
	if err != nil {
		fmt.Println("開啟檔案失敗,錯誤資訊:", err)
		return
	}
	// 為了防止忘記關閉檔案,可使用defer註冊檔案關閉語句
	defer file.Close()
	// Read方法讀取資料
	var tmp = make([]byte, 128)
	// 讀取檔案
	n, err := file.Read(tmp)
	// 碰到 io.EOF 表示檔案讀取到末尾
	if err == io.EOF {
		fmt.Println("檔案讀取完畢")
		return
	}
	if err != nil {
		fmt.Println("讀取檔案失敗,錯誤資訊:", err)
		return
	}
	fmt.Printf("讀取了 %d 位元組資料n", n)
	fmt.Println(string(tmp[:n]))
}

輸出如下內容:

讀取了 24 位元組資料
姓名:夢想橡皮擦

讀取到 24 個位元組,標準的中文佔 3 個位元組。

但是上述程式碼最大的問題就是,我們給變數 tmp,即陣列 tmp 僅設定了 128 位元組,如果待讀取的檔案超過了改值,例如 txt 內容如下所示:

姓名:夢想橡皮擦1
姓名:夢想橡皮擦2
姓名:夢想橡皮擦3
姓名:夢想橡皮擦4
姓名:夢想橡皮擦5

此時執行程式碼,就會發現 Read 函數讀取到第 128 個位元組的時候,就會停止讀取,間接導致讀取到的資料亂碼。

讀取了 128 位元組資料
姓名:夢想橡皮擦1
姓名:夢想橡皮擦2
姓名:夢想橡皮擦3
姓名:夢想橡皮擦4
姓名:夢想橡��

解決該問題,需要用到 for 迴圈讀取檔案資料,程式碼如下:

package main
import (
	"fmt"
	"io"
	"os"
)
func main() {
	// 開啟檔案
	file, err := os.Open("./ca.txt")
	if err != nil {
		fmt.Println("開啟檔案失敗,錯誤資訊:", err)
		return
	}
	defer file.Close()
	// 宣告一個 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("讀取檔案失敗,錯誤資訊:", err)
			return
		}
		// 追加資料
		content = append(content, tmp[:n]...)
	}
	fmt.Println(string(content))
}

上述程式碼宣告了一個動態陣列,即切片,解決了讀取資料不足的問題。

bufio 讀取檔案

該函數可以一次讀取一行資料,範例程式碼如下:

func main() {
	file, err := os.Open("./ca.txt")
	if err != nil {
		fmt.Println("開啟檔案失敗,錯誤資訊:", err)
		return
	}
	defer file.Close()
	reader := bufio.NewReader(file)
	for {
		// 逐行讀取資料
		line, err := reader.ReadString('n')
		if err == io.EOF {
			if len(line) != 0 {
				fmt.Println(line)
			}
			fmt.Println("檔案讀取完畢")
			break
		}
		if err != nil {
			fmt.Println("讀取檔案失敗,錯誤資訊:", err)
			return
		}
		fmt.Print(line)
	}
}

該函數與 Python 中的 readline 具備同樣的效果,接下來演示一下讀取整個檔案,程式碼如下:

package main
import (
	"fmt"
	"io/ioutil"
)
func main() {
	content, err := ioutil.ReadFile("./ca.txt")
	if err != nil {
		fmt.Println("開啟檔案失敗,錯誤資訊:", err)
		return
	}
	fmt.Println(string(content))
}

注意匯入模組的時候,直接匯入了 io 包中的 ioutil 函數。

寫檔案

使用 os.OpenFile() 函數可以指定模式開啟檔案,即可以寫入的方式開啟檔案。

寫入檔案最常用的函數是 WriteWriteString,範例程式碼如下所示:

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("開啟檔案失敗,錯誤資訊:", err)
		return
	}
	defer file.Close()
	name := "橡皮擦"
	file.Write([]byte(name))  //寫入位元組切片
	file.WriteString("夢想橡皮擦") //寫入字串
}

使用該方式寫入檔案,會覆蓋之前的檔案內容,檢視結果可直接開啟目錄下的 ca.txt 進行檢視。

我們將 os.OpenFile("ca.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) 中的引數進行單獨的說明。

第一個參數列示檔名,第二個引數是開啟檔案的模式,具體模式如下所示:

os.O_WRONLY:只寫;

os.O_CREATE:建立檔案;

os.O_RDONLY:唯讀;

os.O_RDWR:讀寫;

os.O_TRUNC:清空;

os.O_APPEND:追加。

可以看到與 Python 中的檔案模式基本一致。

最後一個引數值 0666 表示檔案許可權(八進位制),這與 linux 檔案許可權數位一致,讀 r 等於 4(感謝博友指出該錯誤),寫 w 表示 2,執行 x 等於 1,所以 666 表示的是檔案可讀,可寫。

在檔案寫入部分,還存在 bufio.NewWriter 整行寫入,ioutil.WriteFile 整體寫入等內容,可以學習的時候重點查閱一下。

以上就是Go語言檔案開關及讀寫操作範例的詳細內容,更多關於Go檔案開關讀寫操作的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com