在文本操作过程中经常涉及一些文件拷贝需求,这里介绍几种文件复制技巧。

方法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)声明。

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

复制文件的第二种方法是使用ioutil.ReadFile()和ioutil.WriteFile()职能。第一个函数将整个文件的内容读入字节片,第二个函数将字节片的内容写入文件中。实用程序的逻辑可以在以下GO代码中找到:

除了这两个if块,它们是工作方式的一部分,您可以看到程序的功能在ioutil.ReadFile()和ioutil.WriteFile()陈述

请注意,尽管此技术将复制一个文件,但是当您想要复制大型文件时,它可能并不有效,因为ioutil.ReadFile()也将是巨大的。

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

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

实例一

实例二

//打开源文件
fileRead,err :=os.Open("C:/itcase/test-视频.avi")
if err != nil {
    fmt.Println("Open err:",err)
    return
}
defer fileRead.Close()
//创建目标文件
fileWrite,err :=os.Create("C://itcase/test.avi")
if err != nil {
    fmt.Println("Create err:",err)
    return
}
defer fileWrite.Close()

//从源文件获取数据,放到缓冲区
buf :=make([]byte, 4096)
//循环从源文件中获取数据,全部写到目标文件中
for {
    n,err := fileRead.Read(buf)
    if err != nil && err == io.EOF {
         fmt.Printf("读取完毕,n = d%\n:",n)
         return
    }
    fileWrite.Write(buf[:n]) //读多少、写多少
}

这种技术使用os.Read()用于将输入文件的一小部分读入名为buf和os.Write()将缓冲区的内容写入文件。当读取错误或到达文件末尾时,复制过程停止(io.EOF).这里特别注意for中跳出循环条件,同时注意从buf中读取数据,不能写成fileWrite.Write(buf),这里由于buf中可能存在空,千万注意这里。