当前位置: 首页 > news >正文

go make function_Go中复制文件的3种技巧

aa1ccfb2c9e6d6d4b0e1efd784168374.png

本文将向你展示如何使用Go编程语言复制文件。尽管在Go中复制文件有三种以上的方法,但本文将介绍三种最常见的方法:使用io.Copy()Go库中的函数调用;一次读取所有输入文件并将其写入另一个文件;并使用缓冲区将文件分小块复制。

方法1:使用io.Copy()

该实用程序的第一个版本将使用io.Copy()标准Go库的功能。该实用程序的逻辑可以在该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}

除了测试将要复制的文件是否存在(os.Stat(src))和是否为常规文件(sourceFileStat.Mode().IsRegular())以便可以打开文件进行读取之外,所有工作均由该io.Copy(destination, source)语句完成。该io.Copy()函数返回复制的字节数和在复制过程中发生的第一条错误消息。在Go中,如果没有错误消息,则错误变量的值为nil。

你可以io.Copy()在io软件包文档页面上了解有关该功能的更多信息。

执行cp1.go将生成下一种输出:

$ go run cp1.goPlease provide two command line arguments!$ go run cp1.go fileCP.txt /tmp/fileCPCOPYCopied 3826 bytes!$ diff fileCP.txt /tmp/fileCPCOPY

该技术尽可能简单,但是给开发人员没有灵活性,这并不总是一件坏事。但是,有时开发人员需要或想要决定他们如何读取文件。

方法2:使用ioutil.WriteFile()和ioutil.ReadFile()

复制文件的第二种方法是使用ioutil.ReadFile()和ioutil.WriteFile()函数。第一个函数将整个文件的内容读取到一个字节片中,第二个函数将一个字节片的内容写入一个文件中。

该实用程序的逻辑可以在以下Go代码中找到:

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        }

除了这两个if块(它们是Go的工作方式的一部分)之外,你还可以看到在ioutil.ReadFile()and ioutil.WriteFile()语句中可以找到该程序的功能。

执行cp2.go将生成下一种输出:

$ go run cp2.goPlease provide two command line arguments!$ go run cp2.go fileCP.txt /tmp/copyFileCP$ diff fileCP.txt /tmp/copyFileCP

请注意,尽管此技术将复制文件,但是当你要复制大文件时,它可能效率不高,因为返回的字节片ioutil.ReadFile()也将非常大。

方法3:使用os.Read()和os.Write()

在Go中复制文件的第三种方法是使用cp3.go 将在本节中开发的实用程序。它接受三个参数:输入文件的文件名,输出文件的文件名和缓冲区的大小。

的最重要部分cp3.go位于以下for循环中,可以在copy() function:

 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                }        }

这种技术使用os.Read()用于读取输入文件的一小部分到名为缓冲器buf和os.Write()用于写入该缓冲器中的内容到一个文件。当读取错误或到达文件末尾(io.EOF)时,复制过程停止。

执行cp3.go将生成下一种输出:

fbd785b441b7092c445c35957dc27c69.png

如你所见,缓冲区的大小会极大地影响的性能cp3.go。

做一些基准测试

本文的最后一部分将尝试cp3.go 使用time(1)命令行实用程序比较这三个程序以及各种缓冲区大小的性能。

下面的输出显示的性能cp1.go,cp2.go以及cp3.go复制一个500MB的文件时:

51185052193eb8df24dfa9ae5e08a715.png

输出显示所有三个实用程序的性能都非常相似,这意味着标准Go库的功能非常聪明且经过优化。

现在,让我们测试缓冲区大小如何影响的性能cp3.go。cp3.go以10、20和1,000字节的缓冲区大小执行以在相当快的计算机上复制500MB文件将产生以下结果:

deacbfff41e9e2b68591a44f6a9ace46.png

生成的输出表明,缓冲区越大,cp3.go实用程序的性能越快,这或多或少是期望的。此外,使用小于20字节的缓冲区大小复制大文件是一个非常缓慢的过程,应避免使用。

相关文章:

  • 猪猪宝贝
  • 简述python文件操作_Python文件操作的几个要点与示例
  • 读书小结
  • tomcat线程被打满怎么排查_Tomcat面试题(2020最新版)
  • oc引导开机直接进_超级详细的oc引导制作过程(二)——config.plist的制作,从入门到入土...
  • 2007年你需要知道的五大技术
  • python中reader_关于Python 的这几个技巧,你应该知道
  • SVN时代...
  • sift算法双向匹配剔除不匹配点_【动手学计算机视觉】第七讲:传统目标检测之SIFT特征...
  • SVN应用
  • python怎么训练模型_如何在训练堆叠模型后预测python的数据?
  • 使用者的角度来看SVN
  • python输出文本居中_如何在Tkinter文本小部件中居中文本?
  • SVN pk CVS
  • java api接口怎么写_看看人家那后端API接口写的,那叫一个优雅
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • axios 和 cookie 的那些事
  • docker-consul
  • Docker容器管理
  • GitUp, 你不可错过的秀外慧中的git工具
  • HomeBrew常规使用教程
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • Mac转Windows的拯救指南
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • Spring Cloud Alibaba迁移指南(一):一行代码从 Hystrix 迁移到 Sentinel
  • TypeScript实现数据结构(一)栈,队列,链表
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • win10下安装mysql5.7
  • 区块链技术特点之去中心化特性
  • 我的面试准备过程--容器(更新中)
  • 我的业余项目总结
  • 小程序button引导用户授权
  • 怎么将电脑中的声音录制成WAV格式
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 翻译 | The Principles of OOD 面向对象设计原则
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)关于pipe()的详细解析
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET 中 GetProcess 相关方法的性能
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
  • .Net的DataSet直接与SQL2005交互
  • .NET和.COM和.CN域名区别
  • .NET框架
  • .NET面试题(二)
  • .net知识和学习方法系列(二十一)CLR-枚举
  • :not(:first-child)和:not(:last-child)的用法