美文网首页
Go语言读文件的几种方法

Go语言读文件的几种方法

作者: 高稚商de菌 | 来源:发表于2018-03-05 22:30 被阅读0次

    Go语言中常用的几种文件读写的方法分别为os.Open、bufio和ioutil。下面比较的直接调用File对象的Read函数、bufio的NewReader函数和ioutil的ReadAll的性能

    package main
    import (
        "fmt"
        "time"
        "os"
        "bufio"
        "io/ioutil"
    )
    
    // os.Open
    func read1(filepath string) string {
        f, err := os.Open(filepath)
        if err != nil{  
            panic(err)  
        }
        defer f.Close()
        chunks := make([]byte,1024,1024)
        buf := make([]byte,1024)
        for {
            n, err := f.Read(buf)
            if err != nil || 0 == n {
                break
            }
            chunks = append(chunks, buf[:n]...)
        }
        return string(chunks)
    }
    
    // bufio
    func read2(filepath string) string {
        file, err := os.Open(filepath)
        if err != nil{  
            panic(err)  
        }
        defer file.Close()
        chunks := make([]byte,1024,1024)
        f := bufio.NewReader(file)
        buf := make([]byte,1024)
        for {
            n, err := f.Read(buf)
            if err != nil || 0 == n {
                break
            }
            chunks = append(chunks, buf[:n]...)
        }
        return string(chunks)
    }
    
    // ioutil
    func read3(filepath string) string {
        file, err := os.Open(filepath)
        if err != nil{  
            panic(err)  
        }
        defer file.Close()
        f, _ := ioutil.ReadAll(file)
        txt := string(f)
        return txt
    }
    
    func main() {
        filepath := "somefile.txt"
        t1 := time.Now()
        read1(filepath)
        elapsed1 := time.Since(t1)
        fmt.Println("cost ", elapsed1)
        t2 := time.Now()
        read2(filepath)
        elapsed2 := time.Since(t2)
        fmt.Println("cost ", elapsed2)
        t3 := time.Now()
        read3(filepath)
        elapsed3 := time.Since(t3)
        fmt.Println("cost ", elapsed3)
    }
    
    

    文件大小为48.47M,结果为

    cost  222.050377ms
    cost  111.779435ms
    cost  82.178851ms
    

    具体的性能差异,涉及到源码层面了。应该和源码中使用的buffer和系统调用中使用的buffer有关(是不是这两处的buffer还不一样呢,有空研究一下)。理论上说,系统调用读文件读的缓存区越大,调用次数越少,耗时越少。参考https://segmentfault.com/a/1190000011680507

    使用时,根据需求选择:如果需要一次性读取,用ioutil.ReadFile和ioutil.ReadAll方便;如果需要分块或分行,用bufio的Read、ReadString或者ReadLine更加方便;如果是大文件读写的话,用bufio。

    相关文章

      网友评论

          本文标题:Go语言读文件的几种方法

          本文链接:https://www.haomeiwen.com/subject/fzrkfftx.html