You need to enable JavaScript to run this app.
文档中心
对象存储

对象存储

复制全文
下载 pdf
下载对象
断点续传下载(Android SDK)
复制全文
下载 pdf
断点续传下载(Android SDK)

下载大文件时,可以使用 downloadFile 断点续传下载接口,TOS SDK 可通过 Range 下载的方式分片并发下载大文件,并借助本地 checkpoint 的机制记录已下载成功的分片。当出现网络异常或机器故障等问题导致下载中断,可再次调用该接口以实现续传的效果。

示例代码

以下代码展示如何断点续传下载大对象。

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import com.volcengine.tos.TOSV2;
import com.volcengine.tos.TOSV2ClientBuilder;
import com.volcengine.tos.TosException;
import com.volcengine.tos.model.object.DownloadFileInput;
import com.volcengine.tos.model.object.DownloadFileOutput;
import com.volcengine.tos.model.object.HeadObjectV2Input;

public class DownloadFileExample extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        String endpoint = "your endpoint";
        String region = "your region";
        String accessKey = "your access key";
        String secretKey = "your secret key";
        String securityToken = "your security token";

        String bucketName = "your bucket name";
        String objectKey = "your object key";

        // downloadFilePath 设置待下载的文件路径,建议使用绝对路径,确保路径下不存在文件,否则会将其覆盖。
        // 如果 objectKey 以 "/"(linux 或 macOS 系统) 或 "\"(Windows 系统)结尾,将在本地生成对应空文件夹
        String downloadFilePath = "the path of file to download";
        // taskNum 设置并发上传的并发数,范围为 1-1000
        int taskNum = 5;
        // partSize 设置文件分片大小,范围为 5MB - 5GB,默认为 20MB
        long partSize = 10 * 1024 * 1024;
        // enableCheckpoint 设置是否开启断点续传功能,开启则会在本地记录上传进度
        boolean enableCheckpoint = true;
        // checkpointFilePath 设置断点续传记录文件存放位置,若不设置则默认在 downloadFilePath 路径下生成
        // 其格式为 {downloadFilePath}.{bucket+objectKey+versionID 的 Base64Md5 值}.download
        String checkpointFilePath = "the checkpoint file path";

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display_message);
        TOSV2 tos = new TOSV2ClientBuilder().build(region, endpoint, accessKey, secretKey, securityToken);

        Thread tosThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    HeadObjectV2Input head = new HeadObjectV2Input().setBucket(bucketName).setKey(objectKey);
                    DownloadFileInput input = new DownloadFileInput().setHeadObjectV2Input(head)
                            .setFilePath(downloadFilePath).setEnableCheckpoint(enableCheckpoint)
                            .setCheckpointFile(checkpointFilePath).setPartSize(partSize).setTaskNum(taskNum);
                    DownloadFileOutput output = tos.downloadFile(input);
                    Log.i("downloadFile", "downloadFile succeed, object's etag is " + output.getOutput().getHeadObjectBasicOutput().getEtag());
                    Log.i("downloadFile", "downloadFile succeed, object's crc64 is " + output.getOutput().getHeadObjectBasicOutput().getHashCrc64ecma());
                } catch (TosException e) {
                    Log.e("TosException","downloadFile failed");
                    e.printStackTrace();
                }
            }
        });

        tosThread.start();
    }
}

事件监听功能

downloadFile 接口调用过程会发送创建临时文件、下载分片、重命名临时文件等事件,您可以传入自定义接口来监听下载的相关事件,并实现自定义的业务逻辑。
以下代码展示如何使用事件监听功能。

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import com.volcengine.tos.TOSV2;
import com.volcengine.tos.TOSV2ClientBuilder;
import com.volcengine.tos.TosException;
import com.volcengine.tos.comm.event.DownloadEventType;
import com.volcengine.tos.model.object.DownloadEvent;
import com.volcengine.tos.model.object.DownloadEventListener;
import com.volcengine.tos.model.object.DownloadFileInput;
import com.volcengine.tos.model.object.DownloadFileOutput;
import com.volcengine.tos.model.object.HeadObjectV2Input;

public class DownloadFileWithEventListenerExample extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        String endpoint = "your endpoint";
        String region = "your region";
        String accessKey = "your access key";
        String secretKey = "your secret key";
        String securityToken = "your security token";

        String bucketName = "your bucket name";
        String objectKey = "your object key";

        // downloadFilePath 设置待下载的文件路径,建议使用绝对路径,确保路径下不存在文件,否则会将其覆盖。
        // 如果 objectKey 以 "/"(linux 或 macOS 系统) 或 "\"(Windows 系统)结尾,将在本地生成对应空文件夹
        String downloadFilePath = "the path of file to download";
        // taskNum 设置并发上传的并发数,范围为 1-1000
        int taskNum = 5;
        // partSize 设置文件分片大小,范围为 5MB - 5GB,默认为 20MB
        long partSize = 10 * 1024 * 1024;
        // enableCheckpoint 设置是否开启断点续传功能,开启则会在本地记录上传进度
        boolean enableCheckpoint = true;
        // checkpointFilePath 设置断点续传记录文件存放位置,若不设置则默认在 downloadFilePath 路径下生成
        // 其格式为 {downloadFilePath}.{bucket+objectKey+versionID 的 Base64Md5 值}.download
        String checkpointFilePath = "the checkpoint file path";

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display_message);
        TOSV2 tos = new TOSV2ClientBuilder().build(region, endpoint, accessKey, secretKey, securityToken);

        Thread tosThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    HeadObjectV2Input head = new HeadObjectV2Input().setBucket(bucketName).setKey(objectKey);
                    DownloadEventListener listener = new DownloadEventListener() {
                        @Override
                        public void eventChange(DownloadEvent downloadEvent) {
                            if (downloadEvent.getDownloadEventType() == DownloadEventType.DownloadEventCreateTempFileSucceed) {
                                Log.i("downloadFile", "event change, createTempFile succeed");
                            }
                            if (downloadEvent.getDownloadEventType() == DownloadEventType.DownloadEventCreateTempFileFailed) {
                                Log.i("downloadFile", "event change, createTempFile failed");
                            }
                            if (downloadEvent.getDownloadEventType() == DownloadEventType.DownloadEventDownloadPartSucceed) {
                                Log.i("downloadFile", "event change, downloadPart succeed");
                            }
                            if (downloadEvent.getDownloadEventType() == DownloadEventType.DownloadEventDownloadPartFailed) {
                                Log.i("downloadFile", "event change, downloadPart failed");
                            }
                            if (downloadEvent.getDownloadEventType() == DownloadEventType.DownloadEventDownloadPartAborted) {
                                Log.i("downloadFile", "event change, downloadPart aborted");
                            }
                            if (downloadEvent.getDownloadEventType() == DownloadEventType.DownloadEventRenameTempFileSucceed) {
                                Log.i("downloadFile", "event change, renameTempFile succeed");
                            }
                            if (downloadEvent.getDownloadEventType() == DownloadEventType.DownloadEventRenameTempFileFailed) {
                                Log.i("downloadFile", "event change, renameTempFile failed");
                            }
                        }
                    };
                    DownloadFileInput input = new DownloadFileInput().setHeadObjectV2Input(head)
                            .setFilePath(downloadFilePath).setEnableCheckpoint(enableCheckpoint)
                            .setCheckpointFile(checkpointFilePath).setPartSize(partSize).setTaskNum(taskNum)
                            .setDownloadEventListener(listener);
                    DownloadFileOutput output = tos.downloadFile(input);
                    Log.i("downloadFile", "downloadFile succeed, object's etag is " + output.getOutput().getHeadObjectBasicOutput().getEtag());
                    Log.i("downloadFile", "downloadFile succeed, object's crc64 is " + output.getOutput().getHeadObjectBasicOutput().getHashCrc64ecma());
                } catch (TosException e) {
                    Log.e("TosException","downloadFile failed");
                    e.printStackTrace();
                }
            }
        });

        tosThread.start();
    }
}

暂停或取消断点续传

downloadFile 接口支持您主动暂停或取消断点续传任务。暂停断点续传任务会停止下载,再次调用 downloadFile 时可以从上次暂停的位置继续下载。取消断点续传任务会停止下载,删除本地的 checkpoint 文件和下载的临时文件,再次调用 downloadFile 时会重新开始上传。
以下代码展示如何暂停或取消断点续传。

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

import com.volcengine.tos.TOSV2;
import com.volcengine.tos.TOSV2ClientBuilder;
import com.volcengine.tos.TosException;
import com.volcengine.tos.comm.event.DownloadEventType;
import com.volcengine.tos.model.object.DownloadEvent;
import com.volcengine.tos.model.object.DownloadEventListener;
import com.volcengine.tos.model.object.DownloadFileInput;
import com.volcengine.tos.model.object.DownloadFileOutput;
import com.volcengine.tos.model.object.HeadObjectV2Input;

public class DownloadFileWithCancelExample extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        String endpoint = "your endpoint";
        String region = "your region";
        String accessKey = "your access key";
        String secretKey = "your secret key";
        String securityToken = "your security token";

        String bucketName = "your bucket name";
        String objectKey = "your object key";

        // downloadFilePath 设置待下载的文件路径,建议使用绝对路径,确保路径下不存在文件,否则会将其覆盖。
        // 如果 objectKey 以 "/"(linux 或 macOS 系统) 或 "\"(Windows 系统)结尾,将在本地生成对应空文件夹
        String downloadFilePath = "the path of file to download";
        // taskNum 设置并发上传的并发数,范围为 1-1000
        int taskNum = 5;
        // partSize 设置文件分片大小,范围为 5MB - 5GB,默认为 20MB
        long partSize = 10 * 1024 * 1024;
        // enableCheckpoint 设置是否开启断点续传功能,开启则会在本地记录上传进度
        boolean enableCheckpoint = true;
        // checkpointFilePath 设置断点续传记录文件存放位置,若不设置则默认在 downloadFilePath 路径下生成
        // 其格式为 {downloadFilePath}.{bucket+objectKey+versionID 的 Base64Md5 值}.download
        String checkpointFilePath = "the checkpoint file path";

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display_message);
        TOSV2 tos = new TOSV2ClientBuilder().build(region, endpoint, accessKey, secretKey, securityToken);

        Thread tosThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    HeadObjectV2Input head = new HeadObjectV2Input().setBucket(bucketName).setKey(objectKey);
                    DownloadFileInput input = new DownloadFileInput().setHeadObjectV2Input(head)
                            .setFilePath(downloadFilePath).setEnableCheckpoint(enableCheckpoint)
                            .setCheckpointFile(checkpointFilePath).setPartSize(partSize).setTaskNum(taskNum);
                    // 以下代码通过 DownloadEventListener 监听下载事件。
                    // 如果出现 DownloadEventDownloadPartFailed 事件,即有下载失败的分片时就终止下载任务。
                    // 以下代码仅作为示例,用户可根据业务需要进行使用。
                    boolean isAbort = true;
                    DownloadEventListener listener = new DownloadEventListener() {
                        @Override
                        public void eventChange(DownloadEvent downloadEvent) {
                            if (downloadEvent.getDownloadEventType() == DownloadEventType.DownloadEventDownloadPartFailed) {
                                Log.i("downloadFile", "event change, uploadPart failed");
                                if (input.getCancelHook() != null) {
                                    // 调用 cancel 时,如果 isAbort 为 true,会终止断点续传,删除本地 checkpoint 文件,
                                    // 并清理本地已下载的临时文件。
                                    // 如果 isAbort 为 false,只会暂停当前下载任务,再次调用 downloadFile 可从断点处继续下载。
                                    input.getCancelHook().cancel(isAbort);
                                }
                            }
                        }
                    };
                    input.setCancelHook(true).setDownloadEventListener(listener);
                    DownloadFileOutput output = tos.downloadFile(input);
                    Log.i("downloadFile", "downloadFile succeed, object's etag is " + output.getOutput().getHeadObjectBasicOutput().getEtag());
                    Log.i("downloadFile", "downloadFile succeed, object's crc64 is " + output.getOutput().getHeadObjectBasicOutput().getHashCrc64ecma());
                } catch (TosException e) {
                    Log.e("TosException","downloadFile failed");
                    e.printStackTrace();
                }
            }
        });

        tosThread.start();
    }
}
最近更新时间:2024.02.04 18:31:00
这个页面对您有帮助吗?
有用
有用
无用
无用