解决go获取文件md5值不正确的问题

 更新时间:2024年01月16日 11:46:49   作者:ProblemTerminator  
本文主要介绍了解决go获取文件md5值不正确的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一次偶然的操作,发现了一些端倪,获取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)

即可成功! 快去试试吧!

到此这篇关于解决go获取文件md5值不正确的问题的文章就介绍到这了,更多相关go获取文件md5值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • go mod文件内容版本号简单用法详解

    go mod文件内容版本号简单用法详解

    这篇文章主要为大家介绍了go mod文件内容版本号简单用法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Go语言中使用flag包对命令行进行参数解析的方法

    Go语言中使用flag包对命令行进行参数解析的方法

    这篇文章主要介绍了Go语言中使用flag包对命令行进行参数解析的方法,文中举了一个实现flag.Value接口来自定义flag的例子,需要的朋友可以参考下
    2016-04-04
  • 获取Golang环境变量的三种方式小结

    获取Golang环境变量的三种方式小结

    本文介绍了Golang中获取环境变量的三种方式,包含使用Viper包、GoDotEnv包和os包,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-11-11
  • 一文带你感受Go语言空结构体的魔力

    一文带你感受Go语言空结构体的魔力

    在 Go 语言中,有一种特殊的用法可能让许多人感到困惑,那就是空结构体,本文将对Go空结构体进行详解,准备一杯你最喜欢的饮料或茶,随着本文一探究竟吧
    2023-05-05
  • Golang中反射的常见用法分享

    Golang中反射的常见用法分享

    本篇文章主要为大家详细介绍一些Go语言中常见的反射用法,涵盖了常见的数据类型的反射操作。文中的示例代码讲解详细,感兴趣的可以了解一下
    2023-01-01
  • Go+Vue开发一个线上外卖应用的流程(用户名密码和图形验证码)

    Go+Vue开发一个线上外卖应用的流程(用户名密码和图形验证码)

    这篇文章主要介绍了Go+Vue开发一个线上外卖应用(用户名密码和图形验证码),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • 一文详解Golang如何解决内存溢出

    一文详解Golang如何解决内存溢出

    内存溢出是指程序在运行时超出了分配给它的内存限制,从而导致程序异常或崩溃的现象,本文主要为大家介绍了Golang解决内存溢出的方法,感兴趣的小伙伴可以了解下
    2025-01-01
  • Goland配置leetcode的实现示例

    Goland配置leetcode的实现示例

    本文主要介绍了Goland配置leetcode的实现示例,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-06-06
  • 简单聊一聊Go语言中的数组和切片

    简单聊一聊Go语言中的数组和切片

    数组和切片由于语法十分相似,在使用中容易混淆,要认真区分,下面这篇文章主要给大家介绍了关于Go语言中数组和切片的相关资料,需要的朋友可以参考下
    2021-07-07
  • 解决Golang time.Parse和time.Format的时区问题

    解决Golang time.Parse和time.Format的时区问题

    这篇文章主要介绍了解决Golang time.Parse和time.Format的时区问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04

最新评论