GoLang几种读文件方式的比较

GoLang几种读文件方式的比较

GoLang提供了很多读文件的方式,一般来说常用的有三种。使用Read加上buffer,使用bufio库和ioutil 库。

那他们的效率如何呢?用一个简单的程序来评测一下:

Go代码:

    package main  

    import(  
        "fmt"  
        "os"  
        "flag"  
        "io"  
        "io/ioutil"  
        "bufio"  
        "time"  
    )  

    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]...)  
            // fmt.Println(string(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]...)  
            // fmt.Println(string(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)  
        // fmt.Println(string(fd))  
        return string(fd)  
    }  

    func main(){  

        flag.Parse()  
        file := flag.Arg(0)  
        f,err := ioutil.ReadFile(file)  
        if err != nil{  
            fmt.Printf("%s\n",err)  
            panic(err)  
        }  
        fmt.Println(string(f))  
        start := time.Now()  
        read1(file)  
        t1 := time.Now()  
        fmt.Printf("Cost time %v\n",t1.Sub(start))  
        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))  

    }  

运行命令go run read.go filename, 制定需要读取的文件就可以了。这里我比较了读取13.7MB的日志文件,三种方式分别消耗的时间是:

    Cost time 105.006ms  
    Cost time 68.0039ms  
    Cost time 31.0018ms  

读取29.3MB的媒体文件:

    Cost time 390.0223ms  
    Cost time 194.0111ms  
    Cost time 83.0048ms  

读取302MB的媒体文件:

    Cost time 40.8043338s  
    Cost time 1m5.0407201s  
    Cost time 8.8155043s  

这个差距就很明显了,ioutil提供的方法效率就是高。有空可以再从代码层面再去分析一下。

微信扫一扫交流

作者:ryanemax
微信关注:ryanemax (刘雨飏)
本文出处:https://romantic-hoover-f991f1.netlify.com/cookbook/backend/golangReadFile/
授权协议: CC BY-SA 4.0