断点续传下载是指客户端在从网络上下载资源时,由于某种原因中断下载。再次开启下载时可以从已下载完成的部分开始继续下载未完成的部分,从而节省时间和流量。

当我们在手机端使用视频软件下载视频时,下载期间网络模式从 Wifi 切换到移动网络,此时 App 默认都会中断下载。当再次切换到 Wifi 网络时,由用户手动重新开启下载任务,即开始断点续传下载。

细节分析

If-Range HTTP 请求头字段使得 Range 头字段在一定条件下起作用:
  • 如果字段值中的条件得到满足时,Range 头字段才会起作用。同时服务器返回 206 部分内容状态码,以及 Range 头字段请求的相应部分。
  • 如果字段值中的条件没有得到满足,服务器将会返回 200 OK 状态码,并返回完整的请求资源。
  • 字段值中既可以用 Last-Modified 时间值用作验证,也可以用 ETag 标记作为验证,但不能同时使用 Last-Modified 时间值及 ETag 标记用于验证。

If-Range 头字段通常用于断点续传下载过程中,确保上次下载中断后下载的资源没有发生改变。

使用If-Range时,客户端只需发起一次网络请求,而If-Unmodified-Since或者If-Match在条件判断失败时,会返回 412 前置条件检查失败状态码,客户端需再次开启请求来获取资源。

具体实现

有关 Android 中如何实现对 OSS Object 的断点续传下载,请参考以下 iOS 中的代码实现。如需下载,可自行实现或使用第三方开源的下载框架。

iOS 中断点续传下载 OSS Object 示例代码如下:
//1. 首先使用sdk获取object的下载链接
String signedURLString = ossClient.presignConstrainedObjectURL(bucket, object, expires);

//2. 添加下载任务

        mDownloadManager = DownloadManager.getInstance();
        mDownloadManager.add(signedURLString, new DownloadListner() {
            @Override
            public void onFinished() {
                Toast.makeText(MainActivity.this, "下载完成!", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onProgress(float progress) {
                pb_progress1.setProgress((int) (progress * 100));
                tv_progress1.setText(String.format("%.2f", progress * 100) + "%");
            }

            @Override
            public void onPause() {
                Toast.makeText(MainActivity.this, "暂停了!", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCancel() {
                tv_progress1.setText("0%");
                pb_progress1.setProgress(0);
                btn_download1.setText("下载");
                Toast.makeText(MainActivity.this, "下载已取消!", Toast.LENGTH_SHORT).show();
            }
        });
        
//3.开启下载
        mDownloadManager.download(signedURLString);
        
//4.暂停下载
        mDownloadManager.cancel(signedURLString);
        
//5.继续下载
        mDownloadManager.download(signedURLString);
说明 目前 OSS Server 不支持 If-Range字段。所以还不能使用 NSURLSessionDownloadTask在 Android 中实现断点续传下载。而在 iOS 中使用 NSURLSessionDownloadTask实现断点续传下载时,会发送 If-Range给服务器以确认下载文件是否发生更改。