本篇文章将介绍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/cp1copied 512000000 bytes!real 0m0.980suser 0m0.219ssys 0m0.719s$ time go run cp2.go input /tmp/cp2real 0m1.139suser 0m0.196ssys 0m0.654s$ time go run cp3.go input /tmp/cp3 1000000copying input to /tmp/cp3real 0m1.025suser 0m0.195ssys 0m0.486s
从以上数据来看3种方式的性能非常接近,但依然可以看出go的io标准包的性能更优。
以上就是go语言中拷贝文件的几种常用的方式的详细内容。