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

golang下载、上传文件MD5高效计算方法,利用io.TeeReader函数特性 实时计算文件md5签名

在go语言的开发中,当我们在操作下载或者上传文件对象时, 我们可以利用golang内置的io包中的 TeeReader函数特性,高效实时计算文件的md5值。 方法如下:

TeeReader高效计算文件md5示例

保存上传文件,并使用文件的md5签名.扩展名 作为保存文件名,再读取上传文件的同时计算文件md5签名

// 上传文件  使用文件md5签名.ext 作为文件名
func UploadFile(file *multipart.FileHeader) (string, error) {f, err := file.Open() // 读取文件if err != nil {return "", fmt.Errorf("error reading multipart file: %v", err)}defer f.Close() // 创建文件 defer 关闭// 计算文件md5 这里使用 TreeReader的特性在拷贝文件的同时 高效计算文件md5md5 := md5.New()treeReader := io.TeeReader(f, md5)fmd5 := hex.EncodeToString(md5.Sum(nil)) // 获取上传文件的md5签名字符串// 拼接目标文件 使用文件md5签名.ext 作为文件名dstFile := filepath.Join("upload", fmd5+filepath.Ext(file.Filename) )// 创建目标文件对象dst, err := os.Create(dstFile)if err != nil {return "", fmt.Errorf("error creating dst file: %v", err)}defer dst.Close() // 创建文件 defer 关闭// 从treeReader将文件拷贝到目标文件 dstif _, err = io.Copy(dst, treeReader); err != nil {return "", fmt.Errorf("error Copy file to destination: %v", err)}return dstFile, nil
}

TeeReader函数定义参考


// TeeReader returns a [Reader] that writes to w what it reads from r.
// All reads from r performed through it are matched with
// corresponding writes to w. There is no internal buffering -
// the write must complete before the read completes.
// Any error encountered while writing is reported as a read error.
func TeeReader(r Reader, w Writer) Reader {return &teeReader{r, w}
}type teeReader struct {r Readerw Writer
}func (t *teeReader) Read(p []byte) (n int, err error) {n, err = t.r.Read(p)if n > 0 {if n, err := t.w.Write(p[:n]); err != nil {return n, err}}return
}

总结:golang的io包中的这个TeeReader函数给我们提供了非常高效的文件操作的同时进行其他任务的接口,利用这个特性我们可以在保存文件的同时高效的计算文件的MD5,  也可以利用它来实时的显示文件操作进度条等。

更多使用方法参见  go语言内置io包中TreeReader函数的理解和使用示例_golang io.teereader-CSDN博客

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 数据结构-快速排序与归并排序(递归与非递归)
  • 大数据应用组件
  • C++ | Leetcode C++题解之第327题区间和的个数
  • 编程-笔记三:行为型设计模式-小结
  • 字符函数和字符串函数(2),C语言内存函数
  • JavaScript中的Truthy Falsy值以及等号判断
  • vue3中props无法watch
  • Midjourney入门-提示词基础撰写与公式
  • 01.小迪笔记2024 - day01-Web应用架构搭建站库分离路由访问配置受限DNS解析(不定期更新)
  • 中国第一台B超是在哪里产的?以及多普勒超声和B超、A超的区别
  • 如何选择适合的香港云服务器提供商?
  • 嵌入式人工智能(OpenCV-基于树莓派的人脸识别与入侵检测)
  • AI学习指南深度学习篇-卷积神经网络(CNN)简介
  • unity自动添加头部注释脚本
  • 机器学习——支持向量机(SVM)(1)
  • Babel配置的不完全指南
  • input的行数自动增减
  • Java精华积累:初学者都应该搞懂的问题
  • leetcode98. Validate Binary Search Tree
  • PAT A1120
  • php面试题 汇集2
  • Sass Day-01
  • Swoft 源码剖析 - 代码自动更新机制
  • unity如何实现一个固定宽度的orthagraphic相机
  • 创建一个Struts2项目maven 方式
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 记录一下第一次使用npm
  • 嵌入式文件系统
  • 什么是Javascript函数节流?
  • const的用法,特别是用在函数前面与后面的区别
  • HanLP分词命名实体提取详解
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • ​【经验分享】微机原理、指令判断、判断指令是否正确判断指令是否正确​
  • ​低代码平台的核心价值与优势
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • ### RabbitMQ五种工作模式:
  • #{}和${}的区别是什么 -- java面试
  • #QT 笔记一
  • (2)从源码角度聊聊Jetpack Navigator的工作流程
  • (层次遍历)104. 二叉树的最大深度
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (接上一篇)前端弄一个变量实现点击次数在前端页面实时更新
  • (转) ns2/nam与nam实现相关的文件
  • (转)负载均衡,回话保持,cookie
  • ./configure,make,make install的作用
  • .naturalWidth 和naturalHeight属性,
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET6实现破解Modbus poll点表配置文件
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比