老弟做了个网盘,炸了!
趣讲文件上传功能的巧妙设计
大家好,我是鱼皮。
不知道大家有没有想过制作一款自己的网盘呢?这不,我学编程的老弟小阿巴做了一个,非常激动地找我来体验。
打开网盘,界面仿的还不错,我简单试了下文件的上传和下载,没有什么问题。
正当小阿巴洋洋得意时,我试着上传一个 1 GB 大小的文件。结果文件上传到 99% 时,网络一抖,文件上传失败,竟然还要从 0 开始重新上传?!
小阿巴无奈地挠挠头:网络不好,怪我咯?
我直接一巴掌甩过去,要知道,制作网盘可不是一件容易的事!
先从最基础的功能来说,要实现文件的上传、存储、下载、文件和目录管理。如果要真正上线、开放给其他人使用,还要考虑到权限管理、接口访问、CDN 加速,无论哪点自己来做都是很麻烦的。
所以除了学习之外,如果想要搭建自己的私人网盘,建议直接选择一些开源的,比如主流的 Seafile、Nextcloud、Cloudreve、OwnCloud 都可以。
当然,公用网盘最要命的还是带宽、存储等资源的费用,所以为了节约成本、支持更多用户访问,很多网盘都采取了限速、限制容量策略。
小阿巴:做了网盘这么麻烦啊,我放弃我放弃。。。
我笑到:虽然想做好网盘很难,但我们可以一步步来,学习每个功能中的优秀设计,相信最后也能做出一款不错的网盘。今天就先从 文件上传 讲起吧,解决下刚刚上传失败必须从 0 重新上传的问题等。
文件上传设计
文件上传顾名思义就是把文件从本地电脑发送到存储文件的远程服务器上,小文件的上传倒没有什么好说的,主要考虑的是大文件上传怎么 更快、更稳定、更灵活、更快响应 等等,以提高用户的体验。
这里分享几个经典的大文件上传设计,包括文件分块、并发上传、断点续传、秒传、异步上传。
文件分块
既然小文件的处理相对容易,那不妨在发送前,把大文件分割为多个连续的小文件,一块一块地发送。
此外,需要在发送每一个文件块时,额外传输一些信息,比如当前块数、文件总块数、文件大小、所属原文件标识(MD5)等:
这样,服务器就能一块一块地接收,把这些文件块保存到临时目录中。当接收到最后一块时,把之前的所有文件块再拼接到一起,就能组成完成的原文件啦。
并发上传
将大文件分块后,就可以通过多线程并发上传,同时传输多个块:
要根据网络情况决定是否并发上传、同时并发上传多少个块,不是并发数越多越好。网络好的话,并发数量调大一些,能够大大提高文件整体上传效率;相反,盲目调整并发数,上传可能会更慢。
断点续传
对于大文件来说,上传中断后如果要从 0 开始重传,就太让人崩溃了!
推荐使用断点续传技术,原理很简单,在文件分块的基础上,服务器记录一下原文件对应的上传进度,每接收到一个块,就更新一下进度。这样,即使网络故障导致上传失败,也能从上传进度中知道哪些文件块已上传、接下来需要从哪一块重新开始了,而不用从第 1 块开始重新传输。
该原理同样适用于文件下载。
断点续传有很多种实现方式,自主实现、HTTP 协议 1.1 等,感兴趣的同学可以了解下。
秒传
不知道大家有没有发现,有时,我们上传一个几 GB 的超大文件竟然可以在 1 秒内完成!
这是咋实现的呢?真相只有一个,该文件肯定之前已经被上传过了!
这就是经典的秒传技术。
上传文件前,先在客户端(比如浏览器)根据文件内容计算出文件的 MD5 值,相同内容的文件 MD5 值必然相同。然后在服务器已上传文件数据库中查找该 MD5 对应的文件是否已存在。如果不存在,上传文件并在上传成功后将该文件信息插入数据库,过程如下:
若文件已存在,直接新建一个对该文件的引用就行了,不必重复上传,过程如下:
不过要注意,不同内容文件的 MD5 值也可能会相同(碰撞),导致用户下载到不是自己上传的文件,所以检验重复时,还可以补充一些校验,比如针对文件前几位再生成一个 MD5、用其他 Hash 算法再生成一个校验值等。
异步上传
除了同步上传外,当我们要上传的文件不在本地而是已经存在对应 url 时,也可以采用 全异步上传 的方式,将文件上传变成一个 任务 。
用户输入要上传的文件 url,点击上传后,不需要一直在文件上传页面等着,而是只需要告诉后台 “我要执行文件上传”,并向后台新建一个文件上传任务,就可以快速响应用户了,比如 “文件上传中,请留意通知”。等后台取出并真正完成文件上传的任务后,给用户发送通知就可以了。
整体步骤如下:
最后,如果只是需要在开发中用到文件上传,大可不必自己实现上述功能,用个现成的对象存储服务就好了。比如七牛云,分块上传什么的都给我们做好了,也可以参考七牛云 SDK 文档(https://github.com/qiniu)来了解它们的实现方式。
我是鱼皮,最后再送大家一些 帮助我拿到大厂 offer 的学习资料:
跑了,留下 6T 的资源!
欢迎阅读 我从 0 自学进入腾讯的编程学习、实习、求职、考证、写书经历,不再迷茫!
我学计算机的四年,共勉!
以上就是本期分享,有帮助的话点个赞吧 ❤️
老弟做了个网盘,炸了!相关推荐
- java 爬取百度云盘,python爬虫爬取百度网盘-怎么做一个百度网盘搜索引擎
因为要做去转盘网,所以一定要爬取网盘资源,本来想自己写一个爬虫挺不容易的,不想分享出来,但最后还是决定了拿给大家一起看吧,毕竟有交流才有进步,有兴趣的朋友也可以看看我写的其他日志或者关注我,会发现去转 ...
- python爬虫教学百度云_python爬虫爬取百度网盘-怎么做一个百度网盘搜索引擎
因为要做去转盘网,所以一定要爬取网盘资源,本来想自己写一个爬虫挺不容易的,不想分享出来,但最后还是决定了拿给大家一起看吧,毕竟有交流才有进步,有兴趣的朋友也可以看看我写的其他日志或者关注我,会发现去转 ...
- 卧槽!百度网盘炸了!!!
最近百度网盘搞了个活动,开放了 VIP 的领取限制. 本来还以为他在吹牛逼,没想到点开一看,竟然真的能领取!!! 由于活动力度太大,导致每个用户,最多只能领取一次!!! 我这边试了一下,领取到的网盘 ...
- 笑到最后的百度网盘将何去何从
笑到最后的百度网盘,唯一需要面对的对手,就是它自己. 头图来源 | IC photo 在所有互联网服务中,什么生意最难做?个人网盘,可能是许多人给出的共同答案. 如今,在从业者已经寥寥无几的网盘行业, ...
- 如何邀请好友注册您的网站(模拟百度网盘)
花了一年时间做了个网盘下载站点,有兴趣的朋友可以看看站名:去转盘网 其中有个需求是想模拟百度网盘的邀请好友注册功能,想了很久果然 "皇天不负有心人" ,终于整理出个思路,并 ...
- duilib仿百度网盘界面
duilib仿百度网盘界面 这一篇我们介绍使用DuiEditor做一个百度网盘的demo界面. 这一个版本中做了重大更新,设计界面使用了窗口分割,分别为设计.代码.上下分割.左右分割.并且设计和代码实 ...
- 仿qq空间源码_【每日源码】一个Go语言编写的百度网盘客户端,强力推荐
本月第7个源码推送 仿 Linux shell 文件处理命令的百度网盘命令行客户端. 功能简介: 目录 特色 编译/交叉编译 说明 下载/运行 说明 Windows Linux / macOS And ...
- 内网kift私有网盘如何实现在外网公网访问?快解析映射方案
KIFT是一款面向个人.团队.小型组织的网盘服务器系统,安装运行比较简单,开箱即用,下载解压,双击jar文件即可启动.因为是开源的,不少人选择使用KIFT做开源私有网盘,有能力的大佬还可以对它进行定制 ...
- 网赚网盘赚钱,一个自动来钱的小项目,日入200+!
以往跟大家分享的东西都是一些实操性比较强的,于是就有朋友来问了,说有没有类似像小说项目一样,前期投入进去,后期自动来钱的东西. 喔,想想快要过年了,过年期间很多朋友都是陪在家人身边,可能会缺少精力去打 ...
最新文章
- golang 下划线
- 死磕Java并发:J.U.C之Java并发容器:ConcurrentLinkedQueue
- 从tabBarController的一个item上的控制器跳转到另一个item上的控制器
- python调用ffmpeg_Python - FFmpeg
- sql server中除数为零的处理技巧
- 15优秀免费JQuery 图片 滑动效果
- 软件工程第四次作业——例行报告
- 修改Android模拟器的IMEI号
- 网络何时能ping通?什么情况下不能ping通?
- 爬虫案例:自动登录抽屉新热榜
- sx1278lora模块的常见问题解答
- CRM管理系统查询客户信息
- 【Unity Shader】聚光灯体积光效果的简单实现
- 导出Mysql数据库结构-word格式
- 2022爱分析・数据库厂商全景报告 | 爱分析报告
- nginx 服务器重启命令 关闭
- Linux中正则表达式详细命令及代码(附实验笔记)
- 用Java编写的双色球摇奖系统
- 自定义漂亮的Android SeekBar样式
- 计算直线交点与夹角方法