1. 程式人生 > >GoLang幾種讀檔案方式的比較

GoLang幾種讀檔案方式的比較

    GoLang提供了很多讀檔案的方式,一般來說常用的有三種。使用Read加上buffer,使用bufio庫和ioutil 庫。

那他們的效率如何呢?用一個簡單的程式來評測一下:

Go程式碼  收藏程式碼
  1. package main  
  2. import(  
  3.     "fmt"
  4.     "os"
  5.     "flag"
  6.     "io"
  7.     "io/ioutil"
  8.     "bufio"
  9.     "time"
  10. )  
  11. func read1(path string)string{  
  12.     fi,err := os.Open(path)  
  13.     if err != nil{  
  14.         panic(err)  
  15.     }  
  16.     defer fi.Close()  
  17.     chunks := make([]byte,1024,1024)  
  18.     buf := make([]byte,1024)  
  19.     for{  
  20.         n,err := fi.Read(buf)  
  21.         if err != nil && err != io.EOF{panic(err)}  
  22.         if 0 ==n {break}  
  23.         chunks=append(chunks,buf[:n]...)  
  24.         // fmt.Println(string(buf[:n]))  
  25.     }  
  26.     return string(chunks)  
  27. }  
  28. func read2(path string)string{  
  29.     fi,err := os.Open(path)  
  30.     if err != nil{panic(err)}  
  31.     defer fi.Close()  
  32.     r := bufio.NewReader(fi)  
  33.     chunks := make([]byte,1024,1024)  
  34.     buf := make([]byte,1024)  
  35.     for{  
  36.         n,err := r.Read(buf)  
  37.         if err != nil && err != io.EOF{panic(err)}  
  38.         if 0 ==n {break}  
  39.         chunks=append(chunks,buf[:n]...)  
  40.         // fmt.Println(string(buf[:n]))  
  41.     }  
  42.     return string(chunks)  
  43. }  
  44. func read3(path string)string{  
  45.     fi,err := os.Open(path)  
  46.     if err != nil{panic(err)}  
  47.     defer fi.Close()  
  48.     fd,err := ioutil.ReadAll(fi)  
  49.     // fmt.Println(string(fd))  
  50.     return string(fd)  
  51. }  
  52. func main(){  
  53.     flag.Parse()  
  54.     file := flag.Arg(0)  
  55.     f,err := ioutil.ReadFile(file)  
  56.     if err != nil{  
  57.         fmt.Printf("%s\n",err)  
  58.         panic(err)  
  59.     }  
  60.     fmt.Println(string(f))  
  61.     start := time.Now()  
  62.     read1(file)  
  63.     t1 := time.Now()  
  64.     fmt.Printf("Cost time %v\n",t1.Sub(start))  
  65.     read2(file)  
  66.     t2 := time.Now()  
  67.     fmt.Printf("Cost time %v\n",t2.Sub(t1))  
  68.     read3(file)  
  69.     t3 := time.Now()  
  70.     fmt.Printf("Cost time %v\n",t3.Sub(t2))  
  71. }  

   執行命令go run read.go filename, 制定需要讀取的檔案就可以了。這裡我比較了讀取13.7MB的日誌檔案,三種方式分別消耗的時間是:

Go程式碼  收藏程式碼
  1. Cost time 105.006ms  
  2. Cost time 68.0039ms  
  3. Cost time 31.0018ms  

   讀取29.3MB的媒體檔案:

Go程式碼  收藏程式碼
  1. Cost time 390.0223ms  
  2. Cost time 194.0111ms  
  3. Cost time 83.0048ms  

    讀取302MB的媒體檔案

Go程式碼  收藏程式碼
  1. Cost time 40.8043338s  
  2. Cost time 1m5.0407201s  
  3. Cost time 8.8155043s  

   這個差距就很明顯了,ioutil提供的方法效率就是高。有空可以再從程式碼層面再去分析一下。