生命不止,繼續 go go go !!!
讀寫檔案應該是在開發過程中經常遇到的,今天要跟大家一起分享的就是在golang的世界中,如何讀寫檔案。
使用io/ioutil進行讀寫檔案先回憶下之前的ioutil包介紹:Go語言學習之ioutil包(The way to go)
其中提到了兩個方法:func ReadFile
func ReadFile(filename string) ([]byte, error)1
ReadFile reads the file named by filename and returns the contents. A successful call returns err == nil, not err == EOF. Because ReadFile reads the whole file, it does not treat an EOF from Read as an error to be reported.
func WriteFile
func WriteFile(filename string, data []byte, perm os.FileMode) error1
WriteFile writes data to a file named by filename. If the file does not exist, WriteFile creates it with permissions perm; otherwise WriteFile truncates it before writing.
讀檔案:
package mainimport ( "fmt" "io/ioutil")func main() { b, err := ioutil.ReadFile("test.log") if err != nil { fmt.Print(err) } fmt.Println(b) str := string(b) fmt.Println(str)}12345678910111213141516
寫檔案:
package mainimport ( "io/ioutil")func check(e error) { if e != nil { panic(e) }}func main() { d1 := []byte("hello\ngo\n") err := ioutil.WriteFile("test.txt", d1, 0644) check(err)}123456789101112131415161718
使用os進行讀寫檔案同樣,先回憶下之前的os包的介紹:Go語言學習之os包中檔案相關的操作(The way to go)
首先要注意的就是兩個開啟檔案的方法:func Open
func Open(name string) (*File, error)1
Open opens the named file for reading. If successful, methods on the returned file can be used for reading; the associated file descriptor has mode O_RDONLY. If there is an error, it will be of type *PathError.
讀檔案:
fi, err := os.Open(path) if err != nil { panic(err) } defer fi.Close()123456
func OpenFile需要提供檔案路徑、開啟模式、檔案許可權
func OpenFile(name string, flag int, perm FileMode) (*File, error)1
OpenFile is the generalized open call; most users will use Open or Create instead. It opens the named file with specified flag (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, methods on the returned File can be used for I/O. If there is an error, it will be of type *PathError.
讀檔案:
package mainimport ( "log" "os")func main() { f, err := os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0755) if err != nil { log.Fatal(err) } if err := f.Close(); err != nil { log.Fatal(err) }}12345678910111213141516
讀方法
package mainimport ( "bufio" "fmt" "io" "io/ioutil" "os")func check(e error) { if e != nil { panic(e) }}func main() { f, err := os.Open("/tmp/dat") check(err) b1 := make([]byte, 5) n1, err := f.Read(b1) check(err) fmt.Printf("%d bytes: %s\n", n1, string(b1)) 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)) 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)) _, err = f.Seek(0, 0) check(err) r4 := bufio.NewReader(f) b4, err := r4.Peek(5) check(err) fmt.Printf("5 bytes: %s\n", string(b4)) f.Close()}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
寫方法
package mainimport ( "bufio" "fmt" "io/ioutil" "os")func check(e error) { if e != nil { panic(e) }}func main() { f, err := os.Create("/tmp/dat2") check(err) defer f.Close() d2 := []byte{115, 111, 109, 101, 10} n2, err := f.Write(d2) check(err) fmt.Printf("wrote %d bytes\n", n2) n3, err := f.WriteString("writes\n") fmt.Printf("wrote %d bytes\n", n3) f.Sync() w := bufio.NewWriter(f) n4, err := w.WriteString("buffered\n") fmt.Printf("wrote %d bytes\n", n4) w.Flush()}123456789101112131415161718192021222324252627282930313233343536373839404142
幾種讀取檔案方法速度比較
package mainimport ( "bufio" "fmt" "io" "io/ioutil" "os" "time")func read0(path string) string { f, err := ioutil.ReadFile(path) if err != nil { fmt.Printf("%s\n", err) panic(err) } return string(f)}func read1(path string) string { fi, err := os.Open(path) if err != nil { panic(err) } defer fi.Close() chunks := make([]byte, 1024, 1024) buf := make([]byte, 1024) for { n, err := fi.Read(buf) if err != nil && err != io.EOF { panic(err) } if 0 == n { break } chunks = append(chunks, buf[:n]...) } return string(chunks)}func read2(path string) string { fi, err := os.Open(path) if err != nil { panic(err) } defer fi.Close() r := bufio.NewReader(fi) chunks := make([]byte, 1024, 1024) buf := make([]byte, 1024) for { n, err := r.Read(buf) if err != nil && err != io.EOF { panic(err) } if 0 == n { break } chunks = append(chunks, buf[:n]...) } return string(chunks)}func read3(path string) string { fi, err := os.Open(path) if err != nil { panic(err) } defer fi.Close() fd, err := ioutil.ReadAll(fi) return string(fd)}func main() { file := "test.log" start := time.Now() read0(file) t0 := time.Now() fmt.Printf("Cost time %v\n", t0.Sub(start)) read1(file) t1 := time.Now() fmt.Printf("Cost time %v\n", t1.Sub(t0)) read2(file) t2 := time.Now() fmt.Printf("Cost time %v\n", t2.Sub(t1)) read3(file) t3 := time.Now() fmt.Printf("Cost time %v\n", t3.Sub(t2))}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
執行結果:Cost time 4.0105msCost time 11.5043msCost time 7.0042msCost time 2.4983ms
Cost time 4.4925msCost time 11.0053msCost time 5.0082msCost time 2.9992ms
Cost time 3.9866msCost time 15.0085msCost time 7.5054msCost time 2.5035ms
Cost time 4.9989msCost time 14.0112msCost time 7.5045msCost time 3.508ms
Cost time 3.0043msCost time 15.0265msCost time 8.9884msCost time 2.0036ms