开源项目
首先,放上开源项目地址,基于Unity的下载模块,包含了多线程下载、断点续传的功能,可以直接使用。
https://github.com/GrayGuardian/DownloadFile
实现原理
- 多线程下载
根据文件尺寸,将文件等分为X个数据段,再开启X个线程,每个线程设置下载起始位置,下载对应的数据段,最终按顺序将X个线程返回的下载数据拼接成一个byte[],后续可以将byte[]保存成文件
- 断点续传
断点续传需要下载过程中时时写到本地文件,下载开始时,获取本地文件的尺寸X字节,然后设置以X字节为初始位置下载文件
这里可以发现,无论是多线程下载还是断点续传,都需要设置下载文件的起始位置,HTTP请求头的Range字段,可以实现下载部分资源的功能,C#有直接封装好操作Range的函数:
httpWebRequest.AddRange(long/int range)
- 如果 range 为正,则 range 参数指定范围的起始点。 服务器应该开始从 range 指定的参数到 HTTP 实体中数据的末尾发送数据。
- 如果 range 为负,则 range 参数指定范围的结束点。 服务器应该开始从 HTTP 实体中数据的起始到 range 指定的参数发送数据。
httpWebRequest.AddRange(long/int from, long/int to);
- form:下载起始位置
- to:下载结束位置
工作流
下面仅介绍多线程下载文件到本地的工作流,具备断点续传的功能
- 检查下载文件本地目录是否存在,若不存在,则创建
- 检查是否存在下载临时文件,若存在,则通过临时文件数量、尺寸等参数校验缓存数据是否有效,若无效则删除相关临时文件
- 检查临时文件的数量是否与线程数量一致,若不一致,则创建缺少的临时文件
- 请求URL的头部,获取到文件尺寸Size
- 将文件尺寸Size等分为X份的数据段form与to,将form加上临时文件的尺寸
- 开启X个线程,设置Range字段下载form到to之间的数据,每次读取到数据,直接写入对应的临时文件
- 下载完毕后,创建本地文件,读取临时文件的数据后直接删除,拼接后临时文件数据写入本地文件