1.讀文件
package main import ( "bufio" "fmt" "io" "io/ioutil" "os" ) //讀取文件需要經常進行錯誤檢查,這個幫助方法可以精簡下面的錯誤檢查過程。 func check(e error) { if e != nil { panic(e) } } func main() { //也許大部分基本的文件讀取任務是將文件內容讀取到內存中。 dat, err := ioutil.ReadFile("/tmp/dat") check(err) fmt.Print(string(dat)) //你經常會想對於一個文件是怎么讀並且讀取到哪一部分進行更多的控制。對於這個任務,從使用 os.Open打開一個文件獲取一個 os.File 值開始。 f, err := os.Open("/tmp/dat") check(err) //從文件開始位置讀取一些字節。這里最多讀取 5 個字節,並且這也是我們實際讀取的字節數。 b1 := make([]byte, 5) n1, err := f.Read(b1) check(err) fmt.Printf("%d bytes: %s\n", n1, string(b1)) //你也可以 Seek 到一個文件中已知的位置並從這個位置開始進行讀取。 o2, err := f.Seek(6, 0) check(err) b2 := make([]byte, 2) n2, err := f.Read(b2) check(err) fmt.Printf("%d bytes @ %d: %s\n", n2, o2, string(b2)) //io 包提供了一些可以幫助我們進行文件讀取的函數。例如,上面的讀取可以使用 ReadAtLeast 得到一個更健壯的實現。 o3, err := f.Seek(6, 0) check(err) b3 := make([]byte, 2) n3, err := io.ReadAtLeast(f, b3, 2) check(err) fmt.Printf("%d bytes @ %d: %s\n", n3, o3, string(b3)) //沒有內置的回轉支持,但是使用 Seek(0, 0) 實現。 _, err = f.Seek(0, 0) check(err) //bufio 包實現了帶緩沖的讀取,這不僅對有很多小的讀取操作的能提升性能,也提供了很多附加的讀取函數。 r4 := bufio.NewReader(f) b4, err := r4.Peek(5) check(err) fmt.Printf("5 bytes: %s\n", string(b4)) //任務結束后要關閉這個文件(通常這個操作應該在 Open操作后立即使用 defer 來完成)。 f.Close() } /* $ echo "hello" > /tmp/dat $ echo "go" >> /tmp/dat $ go run reading-files.go hello go 5 bytes: hello 2 bytes @ 6: go 2 bytes @ 6: go 5 bytes: hello */
2.寫文件
package main import ( "bufio" "fmt" "io/ioutil" "os" ) func check(e error) { if e != nil { panic(e) } } func main() { //開始,這里是展示如寫入一個字符串(或者只是一些字節)到一個文件。 d1 := []byte("hello\ngo\n") err := ioutil.WriteFile("/tmp/dat1", d1, 0644) check(err) //對於更細粒度的寫入,先打開一個文件。 f, err := os.Create("/tmp/dat2") check(err) //打開文件后,習慣立即使用 defer 調用文件的 Close操作。 defer f.Close() //你可以寫入你想寫入的字節切片 d2 := []byte{115, 111, 109, 101, 10} n2, err := f.Write(d2) check(err) fmt.Printf("wrote %d bytes\n", n2) //WriteString 也是可用的。 n3, err := f.WriteString("writes\n") fmt.Printf("wrote %d bytes\n", n3) //調用 Sync 來將緩沖區的信息寫入磁盤。 f.Sync() //bufio 提供了和我們前面看到的帶緩沖的讀取器一樣的帶緩沖的寫入器。 w := bufio.NewWriter(f) n4, err := w.WriteString("buffered\n") fmt.Printf("wrote %d bytes\n", n4) //使用 Flush 來確保所有緩存的操作已寫入底層寫入器。 w.Flush() } /* 運行這端文件寫入代碼。 $ go run writing-files.go wrote 5 bytes wrote 7 bytes wrote 9 bytes 然后檢查寫入文件的內容。 $ cat /tmp/dat1 hello go $ cat /tmp/dat2 some writes buffered */