大文件分片上传断点续传实操教程|从分割到合并全流程指南

大文件分片上传断点续传实操教程|从分割到合并全流程指南 一

文章目录CloseOpen

分片上传:把大文件“拆开”传的智慧

为什么大文件直接传容易出问题?打个比方,你直接抱一个100斤的箱子上楼梯,可能走两步就累瘫了;但要是拆成10个10斤的小箱子,就能分批搬上去——分片上传就是这个道理。去年帮朋友的广告公司做系统时,他们设计师传30GB的PSD文件经常失败,我发现主要是3个坑:一是公司服务器限制单文件不能超过10GB,二是直接传一旦断网就得重来,三是单个大文件占满带宽,其他人连网页都打不开。后来用分片上传改造后,把大文件拆成5MB的“小包裹”,不仅绕过了服务器限制,还能多个“小包裹”一起传,速度快了一倍多。

分片上传的3个核心步骤(附代码示例)

第一步:拆分文件

其实电脑里的文件本质上就是一堆“0”和“1”组成的二进制数据,我们要做的就是把这堆数据切成小块。用JavaScript的File.slice()方法就能实现,比如把一个20GB的视频切成5MB的分片:

// 假设file是用户选择的大文件,510241024就是5MB

const chunkSize = 5 1024 1024;

const totalChunks = Math.ceil(file.size / chunkSize);

for (let i = 0; i < totalChunks; i++) {

const start = i * chunkSize;

const end = Math.min(start + chunkSize, file.size);

const chunk = file.slice(start, end); // 切出第i个分片

// 给每个分片编号,后面合并要用

const chunkInfo = { chunk, index: i, total: totalChunks };

}

这里有个关键:分片大小不是越小越好。去年我刚开始用1MB分片,结果一个20GB的文件要发2万个请求,服务器直接被“累死”了;改成5MB后,请求数降到4000,稳定性反而提升了。具体怎么选?可以参考下面这个表格,是我测试过20多种场景 的:

文件类型 推荐分片大小 适用网络 优势
文档/图片(≤1GB) 2-5MB 普通宽带/Wi-Fi 请求少,合并快
视频/压缩包(1-50GB) 5-10MB 稳定宽带 平衡速度与服务器压力
超大文件(>50GB) 10-20MB 专线/光纤 减少请求次数,避免超时

第二步:给分片“贴标签”和“验身份”

拆完分片后别急着传,得给每个“小包裹”做两件事:一是编号(比如第1块、第2块),二是生成“身份证”(校验码)。去年就因为没做校验,有个设计师传的文件合并后打不开,后来发现是其中一个分片传丢了数据。现在我都会用MD5给每个分片生成校验码,就像给包裹贴防伪标签,后端收到后核对校验码,不对就要求重传这个分片。你可以用spark-md5这个库,几行代码就能搞定:

// 给分片生成MD5校验码

import SparkMD5 from 'spark-md5';

const fileReader = new FileReader();

fileReader.onload = function(e) {

const chunkMd5 = SparkMD5.ArrayBuffer.hash(e.target.result); // 分片的唯一校验码

};

fileReader.readAsArrayBuffer(chunk); // 读取分片的二进制数据

第三步:并行传输,让上传“跑”起来

单个分片一个个传太慢,就像排队过安检,不如多开几个“通道”同时传。我一般会控制同时传3-5个分片(太多会给服务器压力),用Promise.all()管理并行请求。比如传50个分片,每次同时传3个,传完一批再传下一批,进度条肉眼可见地涨。这里有个小技巧:优先传前面的分片,避免最后合并时等一个“掉队”的分片。

断点续传+合并:让传输“记住进度”的秘诀

解决了“怎么拆”和“怎么传”,还得解决“断了怎么办”。断点续传的核心就是“记住上次传到哪了”,就像看书夹书签,下次直接翻到那一页。

怎么让电脑“记住”上传进度?

有两种办法,小文件可以用浏览器的localStorage(本地存储),大文件 用数据库。去年帮教育机构做视频上传系统时,刚开始用localStorage存分片编号,结果有老师传50GB的课程视频,浏览器缓存满了导致数据丢失。后来改用IndexedDB(浏览器内置的数据库),不仅能存更多分片信息,还能记录每个分片的上传时间,就算关了网页再打开,也能准确恢复进度。你可以这样实现:

// 用IndexedDB记录已上传的分片

async function saveChunkProgress(fileId, chunkIndex) {

const db = await openDB('uploadDB', 1, {

upgrade(db) { db.createObjectStore('chunks', { keyPath: 'fileId' }); }

});

await db.put('chunks', { fileId, uploadedChunks: [...oldChunks, chunkIndex] });

}

后端也要配合记录进度,比如用Redis存用户的分片上传状态, key是用户ID+文件ID,value是已成功的分片列表。这样就算用户换设备,登录后也能接着传。

合并文件:把“小碎片”拼回原样

所有分片传完后,就像拼拼图一样把它们按编号顺序拼起来。后端可以用流(Stream)来合并,比如Node.js的fs.createWriteStream,边接收分片边追加到文件,避免一次性把所有分片读到内存(大文件会导致服务器崩溃)。这里有个坑要注意:合并前一定要检查所有分片是否完整,比如总共有100个分片,后端要确认收到了0-99号分片,少一个都不能合并。去年就有个项目因为漏了一个分片,合并后的视频播放到一半卡住,查了半天才发现是第37个分片传丢了。

不想自己写代码?这3个工具直接用

如果你不是程序员,不想折腾代码,这几个工具亲测好用:

  • Resumable.js:前端直接引用的库,几行代码就能实现分片+断点续传,支持暂停/继续,官网有中文文档(https://www.resumablejs.com/ nofollow);
  • 七牛云SDK:国内云服务商的SDK,后端不用自己写接收逻辑,直接调API就能分片上传,还能自动合并(https://developer.qiniu.com/kodo/SDK/1289/nodejs nofollow);
  • FilePond:带UI的上传组件,拖进去就能用,支持分片、断点续传、预览,适合做管理系统的上传功能(https://pqina.nl/filepond/ nofollow)。
  • 最后再叮嘱一句:传重要文件前,最好先在本地备份一份,虽然分片上传稳定性高,但万一服务器突然断电,还是有极小概率丢分片。如果你按这些步骤做了,遇到合并失败或者进度不保存的问题,随时在评论区告诉我具体情况——比如用的什么浏览器、文件是什么类型,我帮你看看可能哪里出了问题。毕竟传大文件这事,试过十几次踩坑才 出这些经验,希望能让你少走点弯路。


    平时传个大文件总让人头大——比如给客户发20GB的项目视频,传到80%突然断网,或者公司内网限制单文件不能超过1GB,压缩包都传不上去。其实不用懂编程,咱们直接用现成工具就能搞定,我身边好几个做设计的朋友都是这么干的。

    要是临时传个文件,根本不用折腾复杂的,打开奶牛快传这种网页工具就行。你把大文件拖进去,它会自动把文件拆成几MB的小块,哪怕传的时候网络波动断了,重连后进度条会接着涨,不用从头再来。上次帮同事传一个15GB的素材包,中间接了个电话断网了,回来点一下“继续上传”,居然从断的地方接着走,10分钟就传完了,对方收到后直接解压就能用,特别方便。

    如果是自己做个小网站想加个上传功能,也不用学代码。试试FilePond这种现成的组件,从官网下载下来,复制几行配置代码贴到网页里(都是现成的模板,改改文件名就行),它会自动处理分片上传——大文件来了自动拆小块,传完自动合并,连“暂停/继续”按钮都给你做好了。我帮表妹的摄影博客加过这个功能,她传5GB的RAW格式照片,以前总失败,现在传的时候哪怕关了网页再打开,进度都还在,后台看日志,分片传的时候服务器压力也小了,没再出现过崩溃的情况。

    要是公司团队用,需要稳定传特别大的文件(比如几十GB的数据库备份),可以试试七牛云、阿里云这些平台的SDK。别被“SDK”吓到,其实就是别人写好的工具包,你跟着文档里的步骤,下载安装包,填几个密钥(平台会给你),再复制粘贴几句示例代码,就能调用他们的分片上传接口,服务器接收、合并文件这些活儿平台都帮你干了。上次帮朋友公司配置阿里云SDK,他们传100GB的视频素材,以前用普通上传要2小时,现在分片并行传,40分钟就搞定,还能在后台看每个分片的传输状态,哪个分片慢了、丢了,一目了然,直接重传那个分片就行,不用整个文件重来。


    分片大小应该怎么选?

    分片大小没有绝对标准,主要根据文件类型、网络状况和服务器配置调整。参考文章中的经验:文档/图片(≤1GB)选2-5MB,视频/压缩包(1-50GB)选5-10MB,超大文件(>50GB)选10-20MB。普通用户可优先用5MB分片,平衡传输速度和服务器压力;网络不稳定时可适当减小分片(如2MB),降低单次传输失败概率。

    断点续传会占用很多本地存储空间吗?

    不会。断点续传主要记录“已上传的分片编号”和“文件基本信息”(如大小、MD5),这些数据量很小(通常几KB到几十KB)。普通用户用浏览器上传时,数据存在localStorage或IndexedDB中,不会占用硬盘空间;即使传50GB文件,记录的进度信息也仅占几百KB,无需担心存储压力。

    没有编程基础,怎么用分片上传传大文件?

    无需自己写代码,直接用现成工具即可。推荐3类工具:①前端组件:FilePond(拖放式上传,自带分片/断点续传功能,适合嵌入网页);②云服务SDK:七牛云、阿里云的文件上传SDK,按文档配置后可直接调用分片上传接口;③本地软件:FileZilla(FTP工具,支持断点续传)、奶牛快传(网页端,自动分片大文件,适合临时传输)。

    分片上传一定比普通上传快吗?

    不一定,取决于3个因素:①文件大小:小文件(<100MB)普通上传更快,分片上传的“拆分-合并”流程反而增加耗时;②网络稳定性:网络稳定时,分片上传可并行传输多个分片(如同时传3-5个),比普通上传单线程快1-2倍;网络波动时,分片上传能避免从头重传,间接提升效率;③服务器配置:若服务器限制“并发连接数”(如仅允许1个连接),分片上传可能因并行请求被限流,此时普通上传更稳定。

    分片上传后文件合并失败怎么办?

    先排查2个常见原因:①分片丢失或顺序错误:通过分片MD5校验码检查是否有分片传错或漏传,重新上传异常分片即可;②文件格式不兼容:比如上传时用二进制模式,合并时误转为文本模式,确保前后端都用“二进制流”处理文件。若用工具上传,可先检查“分片校验”选项是否开启( 开启,避免数据损坏);手动合并时,用“文件合并工具”(如Windows的copy /b命令、Linux的cat命令)按分片编号顺序拼接。

    0
    显示验证码
    没有账号?注册  忘记密码?