go 文件讀寫有很多方式
ioutil讀文件
package main import ( "io/ioutil" "fmt" ) func main() { data,err := ioutil.ReadFile("a.txt") #這里返回的data是一個字節切片 if err!=nil{ fmt.Println("File reading error", err) } fmt.Println(string(data)) }
ioutil寫文件
package main import ( "io/ioutil" ) func main() { content := "hello world!" ioutil.WriteFile("a.txt",[]byte(content),0777) //如果文件a.txt已經存在那么會忽略權限參數,清空文件內容。文件不存在會創建文件賦予權限 }
使用os包打開文件
//open函數 func Open(name string) (file *File, err error) Open打開一個文件用於讀取。如果操作成功,返回的文件對象的方法可用於讀取數據;對應的文件描述符具有O_RDONLY模式。如果出錯,錯誤底層類型是*PathError。 package main import ( _"io/ioutil" "os" "fmt" ) func main() { f,_ := os.Open("a.txt") defer f.Close() data := make([]byte, 100) count,_ :=f.Read(data) fmt.Print(string(data[:count])) } //openfile函數 func OpenFile(name string, flag int, perm FileMode) (file *File, err error) OpenFile是一個更一般性的文件打開函數,大多數調用者都應用Open或Create代替本函數。它會使用指定的選項(如O_RDONLY等)、指定的模式FileMode(如0666,即可讀寫,但是不可執行)
打開指定名稱的文件。如果操作成功,返回的文件對象可用於I/O。如果出錯,錯誤底層類型是*PathError。 OpenFile是一個更一般性的文件打開函數,大多數調用者都應用Open或Create代替本函數。它會使用指定的選項(如O_RDONLY等)、指定的模式FileMode(如0666,即可讀寫,但是不可執行)
打開指定名稱的文件。如果操作成功,返回的文件對象可用於I/O。如果出錯,錯誤底層類型是*PathError。 參數flag可以結合使用: os.O_WRONLY | os.O_CREATE | O_EXCL //如果已經存在,則失敗 os.O_WRONLY | os.O_CREATE //如果已經存在,會覆蓋寫,不會清空原來的文件,而是從頭直接覆蓋寫 os.O_WRONLY | os.O_CREATE | os.O_APPEND //如果已經存在,則在尾部添加寫 參數perm: linux中的權限rwx分別對應4 2 1,相加的值為7。如0666,即可讀寫,但是不可執行 package main import ( _"io/ioutil" "os" "fmt" ) func main() { f,_ := os.OpenFile("a.txt",os.O_RDWR |os.O_APPEND,0777)//讀寫模式打開,寫入追加 defer f.Close() add_data :="this is add" num,_:=f.Write([]byte(add_data)) fmt.Println(num) data := make([]byte, 100) count,err :=f.Read(data) if err!=nil{ fmt.Println(err) #這里會返回EOF錯誤,因為寫入完畢后文件指針在最末尾,所以讀取的時候是讀不到內容的,需要重新打開一下這個文件 } fmt.Print(string(data[:count])) }
將文件綁定在二進制文件中
packr
會把靜態文件(例如 .txt
文件)轉換為 .go
文件,接下來,.go
文件會直接嵌入到二進制文件中。packer
非常智能,在開發過程中,可以從磁盤而非二進制文件中獲取靜態文件。在開發過程中,當僅僅靜態文件變化時,可以不必重新編譯。
package main import ( "fmt" "github.com/gobuffalo/packr" ) func main() { box := packr.NewBox("../a.txt") data := box.String("test.txt") fmt.Println("Contents of file:", data) }
逐行讀取文件
package main import ( "bufio" "flag" "fmt" "log" "os" ) func main() { //fptr := flag.String("fpath", "test.txt", "file path to read from") //flag.Parse() f, err := os.Open(“a.txt”) //因為bufio需要的是一個*os.File類型,所以我們換個方式讀取,稍后再介紹一下 if err != nil { log.Fatal(err) } defer func() { if err = f.Close(); err != nil { log.Fatal(err) } }() s := bufio.NewScanner(f) for s.Scan() { fmt.Println(s.Text()) } err = s.Err() if err != nil { log.Fatal(err) } }
分塊讀取文件
當文件非常大時,尤其在 RAM 存儲量不足的情況下,把整個文件都讀入內存是沒有意義的。更好的方法是分塊讀取文件。這可以使用 bufio包來完成。
package main import ( "bufio" "flag" "fmt" "log" "os" ) func main() { //fptr := flag.String("fpath", "test.txt", "file path to read from") //flag.Parse() f, err := os.Open("a.txt") if err != nil { log.Fatal(err) } defer func() { if err = f.Close(); err != nil { log.Fatal(err) } }() r := bufio.NewReader(f) b := make([]byte, 3) for { _, err := r.Read(b) if err != nil { fmt.Println("Error reading file:", err) break } fmt.Println(string(b)) } }