写点什么

Golang 实现文件复制的技巧

用户头像
liuzhen007
关注
发布于: 2021 年 05 月 05 日
Golang实现文件复制的技巧

目录


  • 前言

  • 正文

  • 方法一

  • 方法二

  • 方法三

  • 结尾

前言

昨天我们介绍了 Golang 是如何“增”、“删”、“改”、“查”文件的,相信大家在掌握这些基本常规操作之后,依然意犹未尽。今天我们就补充一下,关于文件操作的另一个知识点————复制文件。

正文

复制文件也是我们开发过程中的常见操作,今天我们就来看看 Golang 语言都有哪些方法来实现文件复制。


大概有三种常用方法,它们各有千秋。


接下来,我们分别介绍。

方法一

第一种方法,使用 io/ioutil 包,分别利用它的读方法————ReadFile()和写方法————WriteFile()。可以轻松实现从源文件中读取内容,再写入到目标文件中。下面通过一段来了解一下这个过程。


实例代码:


package main
import ( "fmt" "io/ioutil" "os")
func main() { // 创建一个文本文件src.txt _, _ = os.Create("src.txt") // ioutil.ReadFile读取文件内容 bytestr, err := ioutil.ReadFile("src.txt") if err != nil { fmt.Println(err) } // ioutil.WriteFile将读取到的文件写入目标文件中 err2 := ioutil.WriteFile("dest.txt", bytestr, os.ModePerm) if err2 != nil { fmt.Println(err2) } else { fmt.Println("拷贝成功。。。") }}
复制代码


代码执行结果:


拷贝成功。。。


不错,我们成功实现了文件复制功能。但是,这个方法存在一个缺点,就是我们在写入目标文件前,首先需要把源文件的内容都读取到内存中。如果是小文件还好,但是如果是大文件,非常大,比如 100G,是不是常规的笔记本就读写爆表啦!


那么,有没有比较好的方法解决这个问题呢?


答案是有的,我下面就来看看。

方法二

刚才提到了复制文件时,方法一存在问题。我们应该怎样避免这样的问题呢?其实,我们在复制文件的时候,没有必要一次性将源文件内容都读取到内存中。我们一部分一部分的拷贝内容,比如申请一段内存空间 2048 字节,然后循环写入读取,一点点的从源文件拷贝到目标文件中。


下面我们通过一段代码来了解一下这个过程。


实例代码:


package main
import ( "fmt" "io" "os")
func main() { // 创建一个文本文件src.txt _, _ = os.Create("src.txt") // 打开源文件 file1, err1 := os.Open("src.txt") if err1 != nil { fmt.Println(err1) }
// 打开目标文件 file2, err2 := os.OpenFile("dest.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm) if err2 != nil { fmt.Println(err2) } // 使用结束关闭文件 defer file1.Close() defer file2.Close()
bytestr := make([]byte, 2048, 2048)
for { n, e := file1.Read(bytestr) if e == io.EOF || n == 0 { fmt.Println("拷贝成功。。。") break } // 循环写入读取到的文件 file2.Write(bytestr[:n]) }}
复制代码


代码执行结果:


拷贝成功。。。


哈哈,不错,确实实现了我们最初的目标,而且还不用担心,内存的过度占用问题。那么,还有没有更加方便的方法呢?


答案是有的。请看方法三。

方法三

现在介绍一种更加简单的方法实现文件复制,不需要我们自己去管理内存,直接使用对应的 Copy() 方法就能实现文件复制。话不多,直接看代码吧。


实例代码:


package main
import ( "fmt" "io" "os")
func main() { // 创建源文件 _, _ = os.Create("src.txt") // 打开源文件 file1, err1 := os.Open("src.txt") if err1 != nil { fmt.Println(err1) }
// 创建目标文件 file2, err2 := os.OpenFile("dest.txt", os.O_RDWR|os.O_CREATE, os.ModePerm) if err2 != nil { fmt.Println(err2) } //使用结束关闭文件 defer file1.Close() defer file2.Close() n, e := io.Copy(file2, file1) if e != nil { fmt.Println(e) } else { fmt.Println("拷贝成功。。。,拷贝字节数:", n) } }
复制代码


代码执行结果:


拷贝成功。。。,拷贝字节数: 0


需要指出的是,大家看到 0 时,不要认为是复制失败了,其实我们创建的源文件 src.txt 中,确实没有任何内容,哈哈。不要误会了,如果不放心,可以参考昨天的文章写入一些内容,再复制文件,看看这个值还是不是 0。

结尾

好了,今天关于 Golang 复制文件的操作就介绍到这里,是不是文件复制也有很多细节需要注意,比如内存问题,路漫漫其修远兮,我将上下而求索。嗯,我们明天继续,晚安各位!

发布于: 2021 年 05 月 05 日阅读数: 10
用户头像

liuzhen007

关注

敲代码,搞开发。 2021.05.01 加入

本人深耕音视频技术,走全栈路线,前后端通吃,兼顾各端与流媒体服务器。 博客主页地址:https://liuzhen.blog.csdn.net 微信公众号:玩转音视频 欢迎交流学习!

评论

发布
暂无评论
Golang实现文件复制的技巧