在 day20時,我們有用到讀取文檔的功能,當時未特別介紹,在這邊來介紹一下關於文檔的讀寫。關於文檔的讀寫,在之前有個大家很常用的函式庫 io/ioutil,該函式庫有完整的讀寫功能,不過自從 go 1.16 版之後,功能都可以透過 io 與 os 取代,功能基本都一樣,就是換了個函式庫,根據 官方 的說法如下:
Deprecated: As of Go 1.16, the same functionality is now provided by package io or package os, and those implementations should be preferred in new code. See the specific function documentation for details.
讀取文檔的方式有三種方式:
一次性讀取文檔全部的程式碼如下:
// 讀取全部
func ReadFileAll(filePath string) []byte {
file, err := os.Open(filePath)
if err == nil {
fmt.Println(err)
}
defer file.Close()
data, err := io.ReadAll(file)
if err != nil {
fmt.Println(err)
}
return data
}
如果要逐行或按字元讀取,一般會額外再引用 bufio 函式庫,該函式庫實現了有緩衝的 I/O。
以下為逐行讀取的方式:
// 逐行讀取
func ReadFileLine(filePath string) []byte {
fi, err := os.Open(filePath)
if err != nil {
panic(err)
}
defer fi.Close()
lines := make([]byte, 0)
r := bufio.NewReader(fi)
for {
line, _, c := r.ReadLine()
if c == io.EOF {
break
}
line = []byte(string(line) + "\n") // 為了與其他結果一樣而多加的一行
lines = append(lines, line...)
}
return lines
}
以下為按字元讀取的方式:
// 讀取字元
func ReadFileChar(filePath string) []byte {
fi, err := os.Open(filePath)
if err != nil {
panic(err)
}
defer fi.Close()
r := bufio.NewReader(fi)
chunks := make([]byte, 0)
buf := make([]byte, 1024) //一次讀取1024個字元
for {
n, err := r.Read(buf)
if err == io.EOF || err != nil {
// fmt.Println(err)
break
}
chunks = append(chunks, buf[:n]...)
}
return chunks
}
以效率來說,效率比較高的方式是第一種,一次性全部讀取完,但是相對來說,記憶體的佔用量也相對最高,但是當要讀取的檔案可能會很大時,不建議使用,因為可能會導致記憶體崩潰,因此讀取文件時可以自行斟酌依情況使用
那寫文檔的方式就沒那麼多的區別,基本上差別主要是在於從頭開始寫,還是接續寫,相對完整的解說,可以看看 參考來源2
從頭開始寫的寫法如下:
func WriteFileCover(fileName string) {
err := os.WriteFile(fileName, str, 0644)
if err != nil {
fmt.Println(err)
}
}
接續寫的寫法如下:
func WriteFileContinue(fileName string) {
f, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println(err)
}
defer f.Close()
_, err = f.WriteString(string(str))
if err != nil {
fmt.Println(err)
}
}
那麼放到連續執行兩次的程式碼與結果分別如下:
func main() {
// 寫入
for i := 0; i < 2; i++ {
WriteFileCover("day22/dat1.yaml")
WriteFileContinue("day22/dat2.yaml")
}
}
dat1.yaml 結果:
hello
go
dat2.yaml 結果:
hello
go
hello
go
https://github.com/luckyuho/ithome30-golang/tree/main/day22