讀取整個檔案
- 整個檔案讀取到記憶體是最基本的檔案操作之一,這需要使用
ioutil包中的ReadFile函式,
package main
import (
"flag"
"fmt"
"io/ioutil"
)
func main() {
fptr := flag.String("path", "test.txt", "待讀取檔案的路徑")
flag.Parse()
data, err := ioutil.ReadFile(*fptr)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(data))
}
- 以上使用的是運行時指定引數
-path=test1.txt來指定讀取的檔案,也可以使用檔案的絕對路徑,
分塊讀取檔案
- 當檔案非常大時,尤其在記憶體不足的情況下,把整個檔案都讀入記憶體是沒有意義的,
- 更好的方法是分塊讀取檔案,這可以使用
bufio包來完成, - 利用
bufio包的'NewReader()'函式實作,其中Read方法可以讀取檔案內容到緩沖的位元組陣列中去,
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
// 打開檔案
f, err := os.Open("test.txt")
if err != nil {
fmt.Println(err)
}
// 延遲關閉檔案
defer func() {
if err := f.Close(); err != nil {
fmt.Println(err)
}
}()
// 檔案讀取器
r := bufio.NewReader(f)
buf := make([]byte, 3) // 便于演示 設定的比較小
str := ""
for {
_, err := r.Read(buf)
if err != nil {
if err == io.EOF {
fmt.Println("檔案讀取完畢!")
} else {
fmt.Println(err)
}
break
}
fmt.Println(string(buf))
str += string(buf)
}
fmt.Println("完整結果如下:\n", str)
}
逐行讀取檔案
- 當檔案比較大時還可以采用逐行讀取的方式實作,
- 利用
bufio包的'NewScanner()'函式實作,其中Scan方法可以判斷是否還有下一行,
Text方法可以獲取當前行,Err方法可以獲取錯誤資訊,
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// 打開檔案
f, err := os.Open("test.txt")
if err != nil {
fmt.Println(err)
}
// 延遲關閉檔案
defer func() {
if err := f.Close(); err != nil {
fmt.Println(err)
}
}()
// 檔案讀取器
s := bufio.NewScanner(f)
str := ""
for s.Scan() {
fmt.Println(s.Text(), "\n-------分隔符--------")
str += s.Text()
}
if s.Err() != nil {
fmt.Println(s.Err().Error())
}
fmt.Println("完整結果如下:\n", str)
}
字串寫入檔案
- 使用 create 創建一個指定名字的檔案,
如果這個檔案已經存在,那么 create 函式將截斷這個檔案,該函式回傳一個檔案描述符,
package main
import (
"fmt"
"os"
)
func main() {
f, err := os.Create("123.txt")
if err != nil {
fmt.Println(err)
}
defer func() {
if err = f.Close(); err != nil {
fmt.Println(err)
}
}()
_, err = f.WriteString("Hello World!")
if err != nil {
fmt.Println(err)
}
fmt.Println("檔案寫入成功!")
}
位元組寫入檔案
- 使用
Write方法可以寫入位元組陣列資料,一般為字符對應的UTF-8的10進制編碼,
package main
import (
"fmt"
"os"
)
func main() {
f, err := os.Create("123.txt")
if err != nil {
fmt.Println(err)
}
defer func() {
if err = f.Close(); err != nil {
fmt.Println(err)
}
}()
bytes := []byte{104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100}
_, err = f.Write(bytes)
if err != nil {
fmt.Println(err)
}
fmt.Println("檔案寫入完成")
}
逐行寫入檔案
- 使用
fmt.Fprintln函式實作檔案的逐行寫入,
package main
import (
"fmt"
"os"
)
func main() {
f, err := os.Create("123.txt")
if err != nil {
fmt.Println(err)
}
defer func() {
if err = f.Close(); err != nil {
fmt.Println(err)
}
}()
lines := []string{"Hello", "GoLang", "World"}
for _, v := range lines {
_, err = fmt.Fprintln(f, v)
if err != nil {
fmt.Println(err)
}
}
fmt.Println("檔案寫入完成.")
}
追加檔案內容
os.OpenFile(name string, flag int, perm FileMode) (*File, error)函式可以指定檔案操作方式,
package main
import (
"fmt"
"os"
)
func main() {
f, err := os.OpenFile("123.txt", os.O_APPEND|os.O_RDONLY, 0644)
if err != nil {
fmt.Println(err)
}
defer func() {
if err = f.Close(); err != nil {
fmt.Println(err)
}
}()
lines := []string{"123", "abc", "!@#"}
for _, v := range lines {
_, err = fmt.Fprintln(f, v)
if err != nil {
fmt.Println(err)
}
}
fmt.Println("檔案追加寫入完成.")
}
并發寫檔案
- 注意檔案寫入時的競態條件,
package main
import (
"fmt"
"math/rand"
"os"
"sync"
)
func main() {
chNum := make(chan int)
chExit := make(chan bool)
wg := sync.WaitGroup{}
// 生產者
for i := 0; i < 100; i++ {
wg.Add(1)
go makeRandom(chNum, &wg)
}
// 消費者
go writeFile(chNum, chExit)
wg.Wait()
close(chNum)
if <-chExit {
fmt.Println("檔案寫入成功.")
} else {
fmt.Println("檔案寫入失敗.")
}
}
func makeRandom(chNum chan int, wg *sync.WaitGroup) {
chNum <- rand.Intn(1000)
wg.Done()
}
func writeFile(chNum chan int, chExit chan bool) {
f, err := os.Create("123.txt")
if err != nil {
fmt.Println(err)
}
defer func() {
if err = f.Close(); err != nil {
fmt.Println(err)
}
}()
for val := range chNum {
_, err = fmt.Fprintln(f, val)
if err != nil {
fmt.Println(err)
}
}
chExit <- true
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/27381.html
標籤:Go
