`
david_je
  • 浏览: 373214 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

GoLang几种读文件方式的比较

    博客分类:
  • go
 
阅读更多

    

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

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

 

    

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提供的方法效率就是高。有空可以再从代码层面再去分析一下。

   

   

分享到:
评论
1 楼 study_c 2017-05-08  
楼主你这不是坑人家么,测试用例都写的是错的。

append效率太低了

测试结果和真是环境完全相反
还有把[]byte 转成string也是低效操作

package main 
 
import( 
    "fmt" 
    "os" 
    "flag" 
    "io" 
    "io/ioutil" 
    "bufio" 
    "time" 

 
func read1(path 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])) 
    } 

 
func read2(path 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])) 
    } 

 
func read3(path string){ 
    fi,err := os.Open(path) 
    if err != nil{panic(err)} 
    defer fi.Close() 
    _,err = ioutil.ReadAll(fi) 
    // fmt.Println(string(fd)) 

 
func main(){ 
    
    flag.Parse() 
    file := flag.Arg(0) 
    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)) 


正确结论是
bufio > ioutil > file.Read

相关推荐

    浅谈GoLang几种读文件方式的比较

    通过运行示例代码并比较不同方法的耗时,我们可以看到,在处理小到中等大小的文件时,`bufio`库通常比`Read`加缓冲区更快,而`ioutil.ReadAll`在小文件中表现良好,但在大文件中性能下降明显。这是因为`ReadAll`会一...

    parquet-go:纯golang库,用于读写镶木地板文件

    支持读/写嵌套/平面拼花文件 使用简单 高性能 安装 将parquet-go库添加到$ GOPATH / src并安装依赖项: go get github.com/xitongsys/parquet-go 例子 example/目录包含几个示例。 local_flat.go示例创建一些数据...

    Go-Golang绑定Mozilla的DeepSpeech语音到文本库

    在本文中,我们将深入探讨如何使用Golang(Go语言)绑定Mozilla的DeepSpeech语音转文本库,以便在Go应用程序中实现高效、准确的语音识别功能。DeepSpeech是Mozilla开源的一个深度学习模型,它能将音频流转换为文字,...

    Python-一份对Golang和Python友好的VIM配置

    配置中对Golang的支持可能包括了以下几点: 1. **Go插件**:如`vim-go`,它提供了许多Go语言相关的功能,如自动完成、语法检查、格式化代码、运行测试、查看Go文档等。 2. **语法高亮**:确保Go代码的关键词、类型和...

    Go-基于Golang的社区系统

    Go(Golang)是由Google开发的一种静态类型的、编译型的、并发型的、垃圾回收的、C/C++风格的编程语言。它旨在提高编程效率,提供简单易读的代码结构,以及强大的并发支持。在“Go-基于Golang的社区系统”项目中,...

    开源项目-golang-go.zip

    这表明该开源项目可能涉及到对Go语言特性的扩展、优化或者是一种全新的实现方式,从而引起了社区的广泛关注和讨论。 在这个压缩包go-master中,我们可以推测它包含了Go项目的源代码,很可能是一个分支或者是某个...

    golang:golang学习记录

    在本文中,我们将深入探讨Go语言,也称为Golang,这是一种由Google开发的现代、高效且简洁的编程语言。Golang的设计目标是提高开发者的生产力,同时提供高性能和并发支持。"golang学习记录"这一标题暗示了我们将探索...

    golang_web:Golang网站

    【正文】 标题 "Golang_web:Golang网站" 指的是一个基于Go语言构建的Web应用程序项目。Go,也称为Golang,是由Google...通过分析项目中的`golang_web-main`文件,我们可以深入理解Go语言在实际Web开发中的应用方式。

    golang将多路复异步io转成阻塞io的方法详解

    为了更好地理解本文主题,我们首先简要回顾几种常见的IO模型: 1. **阻塞IO**:当进程发起一个IO请求后,该进程会被挂起,直至IO操作完成并返回结果。 2. **非阻塞IO**:进程发起IO请求后不会被挂起,而是立即返回...

    cpp-lua扩展库类似于golang的api函数

    标题中的“cpp-lua扩展库类似于golang的api函数”意味着我们要探讨的是一个用C++编写的库,它为Lua脚本语言提供了类似Go语言API的功能。这样的库旨在方便C++程序与Lua交互,使开发者能够利用Lua的脚本能力来增强C++...

    GoLang_Assignment_1

    Go语言,通常被称为Golang,是由Google开发的一种静态类型的、编译式的、并发型的、垃圾回收的编程语言。这个“GoLang_Assignment_1”很可能是针对学习者或者开发者的一个练习项目,旨在帮助他们更好地理解和掌握Go...

    博客:My Tech博客:关于Golang Python Flutter区块链等

    【描述】 "关于Golang Python Flutter区块链等" 揭示了博客的主要内容,即深入探讨这几种技术。Golang是一种由Google开发的静态类型编程语言,以其高效、简洁和并发支持而受到广泛欢迎,常用于构建后端服务和微服务...

    C32特征码快速定位器

    2. **特征码扫描**:然后,工具会遍历文件的每一个字节,与预定义的特征码进行比较。如果找到匹配的部分,就会标记出来。 3. **混淆代码识别**:对于免杀技术,工具可能包含了对混淆代码的识别算法,如API挂钩、...

    Go-用Go编写的Unix文件命令

    Go语言,也被称为Golang,是由Google开发的一种静态类型的、编译式的、并发型且具有垃圾回收功能的编程语言,特别适合构建高效、可靠的系统工具和网络服务。 在Unix系统中,文件命令包括一系列用于创建、查看、移动...

    开源项目-noypi-future.zip

    开源项目“noypi-future.zip”是一个基于Golang语言实现的未来(Futures)库,旨在为Go编程提供一种异步编程模型。Futures是计算机科学中的一个概念,它代表了一个异步计算的结果,允许程序员在计算完成之前进行操作。...

    Go-Go中的线程安全循环缓冲区环形缓冲区实现了io.ReaderWriter接口

    在Go语言中,线程安全的循环缓冲区(也称为环形缓冲区)是一种高效的数据结构,常用于多线程环境中的数据通信和同步。它允许数据在生产者和消费者之间流动,而无需复杂的锁定机制。Go的标准库并没有提供现成的线程...

    开源项目-appscode-go-dns.zip

    这个项目的核心在于它提供了一种标准化的方式来发起DNS查询,并处理响应。通过使用`appscode/go-dns`,开发者可以避免直接与低级的网络I/O和解析过程打交道,而是直接使用高级API来执行DNS查询。这样不仅可以提高...

    使用Go语言开发的Linux权限审计工具.zip

    首先,Go语言(又称Golang)是由Google开发的一种静态类型、编译型、并发型且具有垃圾回收功能的编程语言。它的设计目标是提高开发者的生产力和代码的运行效率,特别适合于构建网络服务和系统工具。在嵌入式系统中,...

    excel表转Lua脚本工具

    Lua作为一种轻量级、高效且易读的脚本语言,常被用于游戏开发和其他配置文件的编写。然而,手动编写Lua脚本可能效率低下且容易出错。为了解决这个问题,出现了"Excel表转Lua脚本工具",它能将整理好的Excel表格数据...

Global site tag (gtag.js) - Google Analytics