关于断点续传

116 天前
 humbass

最近一个项目要用到大文件的断点续传,多大文件呢,大的包可能会有 20G ,目前的做法是

前端取到文件后,按 2m 一个片段进行分片,然后逐个上传 后端收到完整的文件后放在一个隐藏的目录内,等最后的文件传完之后,逐一合并,并移动到指定的文件夹

实现是实现了,最大的问题不是上传,而是合并以及转移文件相当消耗时间

有没有更高级的做法呢?

5020 次点击
所在节点    Node.js
53 条回复
vivisidea
116 天前
是需要完全要自己实现么?你们项目有没有用对象存储?对象存储 sdk 一般都支持这个分片上传+合并操作的

https://aws.amazon.com/cn/blogs/compute/uploading-large-objects-to-amazon-s3-using-multipart-upload-and-transfer-acceleration/
mx1700
116 天前
移动如果同一硬盘不应该耗时啊
合并的方式不太对,应该直接创建完整大小的空文件,上传接口拿到的缓冲数据直接写到完整文件的指定位置,不需要合并操作
humbass
116 天前
@vivisidea 因为是企业内网网络(含广义上的内网)使用,不能使用第三方的云端存储。
misoomang
116 天前
开源的对象存储 minio 是否可以考虑使用搭建
InDom
116 天前
@mx1700 #2 认可 2 楼的思路,分片上传只是在上传过程中分片处理。

保存时可以分片最后合并,也可以直接写到最终文件的对应位置。

自己做一下记录都接收到哪些块了,这样也方便协商未完成的部份。
Ipsum
116 天前
为什么不能直接按全文件大小在指定位置建立空文件,然后 offset 写实际数据进去呢?设置个 cron 。超过 3 天没传完自动删除。
MoHen9
116 天前
分成很多个小文件?说明你实现的断点续传不对,断点续传是一个大文件分成多个请求,每个请求只传自己分好的那一段数据,比如 20 个 G 分成 20 个请求,每个请求传 1G ,第一个请求传从 0 到 1G ,第二个请求从 1G 到 2G ,以依次类推,服务器也是一个文件,根据请求写入文件对应的位置。请求头会携带一些分段的信息,这个有标准的 header ,好像是 range ,可以搜一下
scegg
116 天前
1 建立一个临时文件储存区。
2 上传文件方法分为
( 1 )新建临时文件,body 是文件的第一段,post 成功后将数据保存在临时文件区,文件名可以为一个随机 guid ,返回这个 id 。
( 2 )附加临时文件,body 是文件的第 N 段,将方法 1 返回的 id 作为 query 参数一并提供,post 成功后将新提供的数据附加在这个 id 指定的文件后。
3 在原“使用”文件的位置(例如新建文件的方法),增加临时文件 id 参数。将指定临时文件移动到永久存储区。

客户端流程:
1 打开一个文件。
使用“新建临时文件”方法,传送第一块,得到文件 ID ;使用“附加临时文件”方法,并提交文件 ID ,传送后续的块;使用原业务方法,提交文件 ID ,完成从临时文件到永久存储区的转移和使用。
humbass
116 天前
to: @mx1700 @Ipsum
说的是同一个事,待验证是否可以按区块在预先创建的文件上直接写数据

to: @misoomang
使用开源对象储存,也是一个不错的方式,之前没想到对象存储也有开源的,像这类东西有点大,没信心是否可以驾驭
libaili
116 天前
@humbass #3 可以部署 minio
qdwang
116 天前
@Ipsum 正解
rekulas
116 天前
移动文件应该很快,耗时应该是在合并上,增加了额外的 io 时间

所以最佳方案应该就是预申请空间,然后不同的线程可以在不同的段进行 io 写入不会冲突(如果是单线程写入那就更不会了), 只需要验证分块 hash 正确最后的文件应该就没啥问题了
renmu
116 天前
建议检查代码的实现,理论上不会很耗时
jiangzm
116 天前
为啥一定要按分片存储呢, 直接将缓冲不断写入单文件不好吗? 还是说用缓存文件替代缓冲,不管是处理缓冲区(Buffer)还是缓存文件,其实都需要每收到一次请求及时做写入目标文件处理啊。
humbass
116 天前
@jiangzm 因为要断点续传,直接写入文件,如何告诉客户端从哪里开始上传?后端精确的获得当前文件大小,然后告诉前端从这个位置开始重新上传?
Suaxi
116 天前
领导允许用开源对象存储的话,可以参考一下 minio 的分片上传
salparadise
116 天前
做过类似断点续传,用的 Oss 分片+合并
01802
116 天前
用 syncthing 去传也行,可以自建
guanzhangzhang
116 天前
创建大小文件,http range 和你 server 进程 seek 写就行
linhua
116 天前
@humbass #15 断点续传 和 断点下载是差不多的。一般的做法是 先建立一个 实际文件大小的 占位文件,还有一个 存储当前进度信息的 文本文件

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1067088

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX