欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

golang-关于调用完io.Copy()方法之后文件上传失败的一种现象描述

程序员文章站 2022-06-10 11:12:19
...

现象描述:在调用完io.Copy()方法之后,再次直接读取文件,读取的结果为空。具体代码如下:

package main

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

func main(){

	file,_ := os.Open("D:/autoUpload/xixi.txt")
        defer file.Close()
	bytes1 , _ := ioutil.ReadAll(file)
	fmt.Println("文本内容:",string(bytes1))

        //求文件哈希值
	h := sha256.New()
	io.Copy(h,file)
	sum := h.Sum(nil)
	currentHash := hex.EncodeToString(sum)
	fmt.Println("当前文件的hash码为:",currentHash)

	bytes2 , _ := ioutil.ReadAll(file)
	fmt.Println("文本内容:",string(bytes2))

        //文件上传,自定义的方法,读者可忽略
	UploadFile("http://127.0.0.1:8000", nil, "file", "xixi.txt", file)
}

运行之后打印结果如下:

文本内容: 这是文本文件的内容,this is the content of text file
当前文件的hash码为: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
文本内容: 

可以看到:在第二次打印文件内容时,文件内容为空了,这就会导致在UploadFile文件上传函数被调用时,文件的内容也不会被上传到服务器。

造成这种现象的原因主要是:我们在第二次打印文件内容之前对文件做了一次求hash值运算,其中调用了io.Copy()方法 ,io.Copy()方法会读取文件内容,并移动文件指针。在调用完io.Copy()方法之后,文件指针是被移到文件的末尾处了,所以在第二次读取文件文件的内容为空。

解决方法:在第二次使用文件之前调用file.seek(0,0)方法,该方法会将文件指针移到开头。具体代码如下:

package main

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

func main(){

	file,_ := os.Open("D:/autoUpload/xixi.txt")
	defer file.Close()
	bytes1 , _ := ioutil.ReadAll(file)
	fmt.Println("文本内容:",string(bytes1))

        //求文件的hash值
	h := sha256.New()
	io.Copy(h,file)
	sum := h.Sum(nil)
	currentHash := hex.EncodeToString(sum)
	fmt.Println("当前文件的hash码为:",currentHash)

	file.Seek(0,0)//将文件指针移到文件开头

	bytes2 , _ := ioutil.ReadAll(file)
	fmt.Println("文本内容:",string(bytes2))

	//文件上传,自定义的方法,读者可忽略
	UploadFile("http://127.0.0.1:8000", nil, "file", "xixi.txt", file)

}

再次运行可以看到打印结果如下:

文本内容: 这是文本文件的内容,this is the content of text file
当前文件的hash码为: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
文本内容: 这是文本文件的内容,this is the content of text file

有关file.Seek()方法的参数具体含义如下:
 

func (f *File) Seek(offset int64, whence int) (ret int64, err error)
Seek函数将下一次在文件上读取或写入的偏移量(文件指针)设置为指定偏移量(相对于whence做offset个偏移)。

参数whence的进一步解释:0表示相对于文件原点,1表示相对于当前偏移量,2表示相对于末尾。

返回结果为新的偏移量和错误(如果有)。

 file.Seek(0,0)的含义就是相对于文件原点偏移0个量,即文件的开头。