文件上传与下载:大文件分片处理
# 文件上传与下载:大文件分片处理摘要:Go文件上传下载实战涵盖multipart表单上传、流式处理避免OOM、分片上传协议设计、断点续传下载附临时文件泄漏踩坑经验。去年公司做了个视频处理平台用户上传视频做转码。测试时几十MB的文件一切正常上线第一天就有用户传了个4GB的高清视频服务器直接OOM重启了。排查发现是r.ParseMultipartForm的锅它会把上传文件读进内存超过maxMemory才写临时文件。我们设了1GB的maxMemory想提速大文件直接把内存吃光了。流式处理避免OOM小文件用ParseMultipartForm够了。大文件必须用MultipartReader流式读取内存占用恒定。packagemainimport(fmtionet/httpospath/filepath)funcuploadStreamHandler(w http.ResponseWriter,r*http.Request){// 限制请求体总大小1GB上限r.Bodyhttp.MaxBytesReader(w,r.Body,130)deferr.Body.Close()// 用MultipartReader流式读取不预加载到内存reader,err:r.MultipartReader()iferr!nil{http.Error(w,解析multipart失败,http.StatusBadRequest)return}// 逐个part处理for{part,err:reader.NextPart()iferrio.EOF{break// 所有part读完}iferr!nil{http.Error(w,读取part失败,http.StatusBadRequest)return}// 跳过普通表单字段只处理文件ifpart.FileName(){continue}// 清理文件名防止路径穿越攻击filename:filepath.Base(part.FileName())dst,err:os.Create(filepath.Join(uploads,filename))iferr!nil{http.Error(w,创建文件失败,http.StatusInternalServerError)return}// 32KB缓冲区流式复制不管文件多大内存占用恒定buf:make([]byte,32*1024)_,errio.CopyBuffer(dst,part,buf)dst.Close()iferr!nil{http.Error(w,保存文件失败,http.StatusInternalServerError)return}fmt.Fprintf(w,上传成功: %s\n,filename)}}funcmain(){os.MkdirAll(uploads,0755)http.HandleFunc(/upload,uploadStreamHandler)http.ListenAndServe(:8080,nil)}用MultipartReader内存占用恒定传1GB和1TB的文件内存消耗一样。代价是手动遍历每个part。分片上传实现文件特别大时10GB以上网络不稳定会导致上传失败重来。分片上传把文件切块独立上传失败只需重传那一片。packagemainimport(crypto/md5encoding/hexfmtionet/httpospath/filepathstrconv)// 分片上传接口接收一个分片funcuploadChunkHandler(w http.ResponseWriter,r*http.Request){// 从查询参数获取文件ID和分片序号fileID:r.URL.Query().Get(fileId)chunkIndex:r.URL.Query().Get(chunkIndex)// 为每个文件创建临时目录存放分片chunkDir:filepath.Join(chunks,fileID)os.MkdirAll(chunkDir,0755)// 读取上传的分片数据并保存file,_,err:r.FormFile(chunk)iferr!nil{http.Error(w,读取分片失败,http.StatusBadRequest)return}deferfile.Close()// 创建分片文件必须检查错误否则dst为nil后续io.Copy会panicdst,err:os.Create(filepath.Join(chunkDir,chunkIndex))iferr!nil{http.Error(w,创建分片文件失败,http.StatusInternalServerError)return}deferdst.Close()// 写入分片数据检查错误防止静默失败if_,err:io.Copy(dst,file);err!nil{http.Error(w,写入分片失败,http.StatusInternalServerError)return}fmt.Fprintf(w,分片 %s 上传成功\n,chunkIndex)}// 合并分片接口把所有分片合成完整文件funcmergeChunksHandler(w http.ResponseWriter,r*http.Request){fileID:r.URL.Query().Get(fileId)filename:r.URL.Query().Get(filename)totalChunks,_:strconv.Atoi(r.URL.Query().Get(totalChunks))// 创建最终文件dst,err:os.Create(filepath.Join(uploads,filename))iferr!nil{http.Error(w,创建文件失败,http.StatusInternalServerError)return}deferdst.Close()// 按顺序读取分片追加到最终文件同时计算MD5校验完整性hasher:md5.New()fori:0;itotalChunks;i{chunkFile,err:os.Open(filepath.Join(chunks,fileID,strconv.Itoa(i)))iferr!nil{http.Error(w,fmt.Sprintf(分片 %d 不存在,i),http.StatusBadRequest)return}// 同时写入目标文件和hash计算器检查错误防止合并出坏文件if_,err:io.Copy(io.MultiWriter(dst,hasher),chunkFile);err!nil{chunkFile.Close()http.Error(w,fmt.Sprintf(分片 %d 合并失败,i),http.StatusInternalServerError)return}chunkFile.Close()}md5sum:hex.EncodeToString(hasher.Sum(nil))os.RemoveAll(filepath.Join(chunks,fileID))// 清理临时分片fmt.Fprintf(w,合并成功MD5: %s\n,md5sum)}funcmain(){os.MkdirAll(uploads,0755)os.MkdirAll(chunks,0755)http.HandleFunc(/upload/chunk,uploadChunkHandler)http.HandleFunc(/upload/merge,mergeChunksHandler)http.ListenAndServe(:8080,nil)}客户端把文件切成5MB一块上传每块带fileId和chunkIndex。所有分片上传完后调merge接口合并合并时计算MD5验证完整性。断点续传下载大文件下载用HTTP Range请求实现断点续传Go标准库已内置。packagemainimport(net/httpos)funcdownloadHandler(w http.ResponseWriter,r*http.Request){filename:r.URL.Query().Get(file)file,err:os.Open(uploads/filename)iferr!nil{http.Error(w,文件不存在,http.StatusNotFound)return}deferfile.Close()stat,_:file.Stat()// 设置响应头声明支持Range请求w.Header().Set(Content-Disposition,attachment; filenamefilename)w.Header().Set(Accept-Ranges,bytes)// ServeContent自动解析Range头返回206和对应数据段// 客户端断线重连带 Range: bytes1048576- 即可续传http.ServeContent(w,r,filename,stat.ModTime(),file)}funcmain(){http.HandleFunc(/download,downloadHandler)http.ListenAndServe(:8080,nil)}http.ServeContent自动处理Range请求返回206状态码客户端断线重连带上Range头即可续传。独家踩坑:临时文件泄漏上线后磁盘空间每隔几天就满了。查了半天发现是r.ParseMultipartForm的临时文件没清理。Go处理multipart表单时超过maxMemory会写临时文件到os.TempDir()在RemoveAll()调用时删除。用MultipartReader流式处理则没有临时文件。旧接口还在用ParseMultipartForm上传完没调RemoveAll()runtime不会自动清理文件一直留在磁盘上。// 修复方案加defer清理临时文件funcuploadFixed(w http.ResponseWriter,r*http.Request){r.ParseMultipartForm(3220)ifr.MultipartForm!nil{deferr.MultipartForm.RemoveAll()// 关键这行}file,_,_:r.FormFile(file)// ... 处理文件 ...}加了一行defer r.MultipartForm.RemoveAll()就解决了。开发环境难发现单次临时文件才几十MB。生产环境高并发临时文件堆积就爆磁盘。对比分析方案内存占用支持大文件断点续传实现复杂度ParseMultipartForm高差不支持简单MultipartReader流式极低好不支持中等分片上传极低极好支持复杂Java用Spring的MultipartFile底层原理类似但Go的io.Copy更简洁。Python的Django没有流式API处理超大文件不如Go灵活。总结核心原则就是流式处理别把整个文件读进内存。小文件用ParseMultipartForm大文件用MultipartReader超大文件用分片上传加断点续传。临时文件清理也别忽略上线后迟早要还的。下一篇聊JWT认证与授权讲讲无状态认证的完整实现方案。

相关新闻

IntelliJ文本处理插件 String Manipulation 实测指南:50余种文本操作让编码效率翻倍

IntelliJ文本处理插件 String Manipulation 实测指南:50余种文本操作让编码效率翻倍

IntelliJ文本处理插件 String Manipulation 实测指南:50余种文本操作让编码效率翻倍 【免费下载链接】StringManipulation IntelliJ plugin - https://plugins.jetbrains.com/plugin/2162 项目地址: https://gitcode.com/gh_mirrors/st/StringManipulation 周…

2026/8/16 16:20:56 阅读更多 →
基于SpringBoot的实训项目管理平台系统(源码+lw+部署文档+讲解等)

基于SpringBoot的实训项目管理平台系统(源码+lw+部署文档+讲解等)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/16 16:20:56 阅读更多 →
G-Helper散热调优指南:一款软件让华硕笔记本温度直降14°C

G-Helper散热调优指南:一款软件让华硕笔记本温度直降14°C

G-Helper散热调优指南:一款软件让华硕笔记本温度直降14C 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, …

2026/8/16 16:19:56 阅读更多 →

最新新闻

Qwen3.8-27B-FP8模型亮点多,基准测试表现出色,使用方法大揭秘!

Qwen3.8-27B-FP8模型亮点多,基准测试表现出色,使用方法大揭秘!

【Hugging Face导航介绍】有Hugging Face标志,其导航栏包含模型、数据集、空间、存储桶(新)、文档、企业版、定价等选项。网站部分有任务、HuggingChat、集合、语言、组织;社区部分有博客、帖子、每日论文、硬件、学习、Discord、…

2026/8/16 16:57:13 阅读更多 →
IR2184从入门到精通

IR2184从入门到精通

IR2184 从入门到精通:一文吃透这颗经典半桥栅极驱动芯片 目录 认识 IR2184引脚与封装详解工作原理深入典型应用电路实战:驱动半桥 / 电机 / 降压电路选型与参数计算常见问题与调试技巧进阶与学习路线参考资料 一、认识 IR2184 1.1 为什么需要栅极驱动…

2026/8/16 16:57:13 阅读更多 →
降AIGC率工具实测:2026年六款逐一打分,差距很大

降AIGC率工具实测:2026年六款逐一打分,差距很大

六月盲审季,群里好几个同学在喊AIGC检测超标。有个初稿查出来62%,导师直接打回要求重写。降AIGC率工具到底有没有用,哪款效果实在,我花了两周时间,用同一段论文做了次横向测试。下面把过程、评分和结论一次性说清楚。 …

2026/8/16 16:57:13 阅读更多 →
Android视频裁剪终极方案:K4L VideoTrimmer开源库快速集成指南

Android视频裁剪终极方案:K4L VideoTrimmer开源库快速集成指南

Android视频裁剪终极方案:K4L VideoTrimmer开源库快速集成指南 【免费下载链接】k4l-video-trimmer A library with UI and mechanisms to trim local videos on Android applications. 项目地址: https://gitcode.com/gh_mirrors/k4/k4l-video-trimmer 做 A…

2026/8/16 16:57:13 阅读更多 →
Java 面试实战:Spring Boot + Kafka + Redis + MyBatis + Spring Security 高并发电商场景深挖

Java 面试实战:Spring Boot + Kafka + Redis + MyBatis + Spring Security 高并发电商场景深挖

Java 面试实战:Spring Boot Kafka Redis MyBatis Spring Security 高并发电商场景深挖场景:互联网大厂 Java 求职者面试人物:严肃面试官 vs 搞笑的水货程序员「燕双非」第一轮:订单链路基础与并发控制面试官:你先说…

2026/8/16 16:57:13 阅读更多 →
Genesis Plus GX 完整避坑指南:一次搞定世嘉全系 8/16 位模拟

Genesis Plus GX 完整避坑指南:一次搞定世嘉全系 8/16 位模拟

Genesis Plus GX 完整避坑指南:一次搞定世嘉全系 8/16 位模拟 【免费下载链接】Genesis-Plus-GX An enhanced port of Genesis Plus - accurate & portable Sega 8/16 bit emulator 项目地址: https://gitcode.com/gh_mirrors/ge/Genesis-Plus-GX Genesi…

2026/8/16 16:56:12 阅读更多 →

日新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/16 0:00:54 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/16 0:00:55 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/16 0:03:55 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/16 0:00:54 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/16 0:00:55 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/16 0:03:55 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/16 6:00:23 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/16 6:00:24 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/16 6:00:27 阅读更多 →