美文网首页Golang开发轻松学GolangGo知识库
Go语言中拷贝文件的几种常用的方式及性能对比

Go语言中拷贝文件的几种常用的方式及性能对比

作者: freelang | 来源:发表于2018-07-03 07:26 被阅读9次

    Go语言中拷贝文件的几种常用的方式

    简介

    本篇文章将介绍Go语言中,最最最常用的3种拷贝文件的方法,这三种方法各有利弊,我们只需要在应用中选择最合适的即可,不必盲目追求性能。

    方法1

    第一个方法将使用标准Go库的io.Copy()函数。以下是使用io.Copy()实现的拷贝文件代码片段:

    
    func copy(src, dst string) (int64, error) {
            sourceFileStat, err := os.Stat(src)
            if err != nil {
                    return 0, err
            }
    
            if !sourceFileStat.Mode().IsRegular() {
                    return 0, fmt.Errorf("%s is not a regular file", src)
            }
    
            source, err := os.Open(src)
            if err != nil {
                    return 0, err
            }
            defer source.Close()
    
            destination, err := os.Create(dst)
            if err != nil {
                    return 0, err
            }
            defer destination.Close()
            nBytes, err := io.Copy(destination, source)
            return nBytes, err
    }
    
    

    方法二

    第二中方法是使用ioutil包中的 ioutil.WriteFile()ioutil.ReadFile(),但由于使用一次性读取文件,再一次性写入文件的方式,所以该方法不适用于大文件,容易内存溢出。

    
     input, err := ioutil.ReadFile(sourceFile)
            if err != nil {
                    fmt.Println(err)
                    return
            }
    
            err = ioutil.WriteFile(destinationFile, input, 0644)
            if err != nil {
                    fmt.Println("Error creating", destinationFile)
                    fmt.Println(err)
                    return
            }
    
    

    方法三

    最后是使用os包中的os.Read()os.Write(),此方法是按块读取文件,块的大小也会影响到程序的性能。

    
      buf := make([]byte, BUFFERSIZE)
            for {
                    n, err := source.Read(buf)
                    if err != nil && err != io.EOF {
                            return err
                    }
                    if n == 0 {
                            break
                    }
    
                    if _, err := destination.Write(buf[:n]); err != nil {
                            return err
                    }
            }
    
    

    性能

    这三种方式都能很方便的实现拷贝文件功能,那他们的性能如何呢,下面我们来尝试对比一下。三种方式都来拷贝同一个500M的文件,

    以下是拷贝文件的时间明细(cp1.go是第一种方式,cp2.go是第二种方式,cp3.go是第三种方式)

    
    $ ls -l INPUT
    -rw-r--r--  1 mtsouk  staff  512000000 Jun  5 09:39 INPUT
    $ time go run cp1.go INPUT /tmp/cp1
    Copied 512000000 bytes!
    
    real    0m0.980s
    user    0m0.219s
    sys     0m0.719s
    $ time go run cp2.go INPUT /tmp/cp2
    
    real    0m1.139s
    user    0m0.196s
    sys     0m0.654s
    $ time go run cp3.go INPUT /tmp/cp3 1000000
    Copying INPUT to /tmp/cp3
    
    real    0m1.025s
    user    0m0.195s
    sys     0m0.486s
    
    

    从以上数据来看3种方式的性能非常接近,但依然可以看出Go的io标准包的性能更优。


    相关文章

      网友评论

        本文标题:Go语言中拷贝文件的几种常用的方式及性能对比

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