一次偶然的操作,发现了一些端倪,获取md5时如下是常规操作:
?? ?md5hash := md5.New()
?? ?
?? ?file, _ := os.Open(filename)
?? ?defer file.Close()
?? ?
?? ?_, err := io.Copy(md5hash, file) ?// file 为*os.File类型,即读取文件后的文件对象
?? ?if err != nil {
?? ??? ?return err
?? ?}
?? ?md5Str := fmt.Sprintf("%x", md5hash.Sum(nil))
正常情况下,md5Str就是我们想要的。但是再看如下这种情况:
?? ?// 创建目标文件,其它两个文件将合并到此文件
?? ??? ?dstFile, err := os.Create("path")
?? ??? ?if err != nil {
?? ??? ??? ?return
?? ??? ?}
?? ??? ?defer dstFile.Close()
?? ??? ?srcFile1, openErr := os.Open(filePath)
?? ??? ?if openErr != nil {
?? ??? ??? ?return
?? ??? ?}
?? ??? ?defer srcFile1.Close()
?? ??? ?
?? ??? ?srcFile2, openErr := os.Open(filePath)
?? ??? ?if openErr != nil {
?? ??? ??? ?return
?? ??? ?}
?? ??? ?defer srcFile2.Close()
?? ??? ?// 暂时去掉错误处理
?? ??? ?io.Copy(dstFile, srcFile1)
?? ??? ?io.Copy(dstFile, srcFile2)
?? ??? ?
?? ??? ?// 此时按理说dstFile应该就是我们想要的结果了,基于dstFile对象获取md5
?? ??? ?// 此位置标记为x
?? ??? ?
?? ??? ?md5hash := md5.New()
?? ??? ?totalSize, err := io.Copy(md5hash, dstFile) ?
?? ??? ?if err != nil {
?? ??? ??? ?return err
?? ??? ?}
?? ??? ?md5Str := fmt.Sprintf("%x", md5hash.Sum(nil)) ?// 拿到的md5Str
接下来是md5对比流程,将源文件md5和dstFile的md5对比,结果发现不相等。。。
等如上流程执行完,发现两个md5不相等,但文件实际上完全一样,合并一切正常,那问题出在了哪里?
就是出在最后计算md5值上,在执行两次io.Copy后,我们需要的全部内容已经全部到了dstFile文件里,但此时要注意的是,经过两次io.Copy,dstFile对象已指向文件末尾,此时去拿md5拿到的结果相当于是基于空内容计算的(需要从开始位置计算md5),必然不正确,此时应当在x位置重置偏移量为开始位置,即:
?file.Seek(0, 0)
即可成功! 快去试试吧!
?